summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeemu Suo-Anttila <teemusa@vaadin.com>2015-07-02 17:34:27 +0300
committerHenri Sara <hesara@vaadin.com>2015-07-10 11:11:32 +0000
commit40dcbc3cfaa438c9b879720c9012331dd85ca694 (patch)
tree52afe832e37b50ca8fbe7b67f7ce35acb89613ba
parent4fce93896627b862587533e4bd3b71b0e7a3a6b2 (diff)
downloadvaadin-framework-40dcbc3cfaa438c9b879720c9012331dd85ca694.tar.gz
vaadin-framework-40dcbc3cfaa438c9b879720c9012331dd85ca694.zip
Refactor RpcDataProviderExtension to use DataGenerators
Change-Id: I8c809b6fac827df730c6622fb6790410c6c5bd81
-rw-r--r--client/src/com/vaadin/client/connectors/GridConnector.java33
-rw-r--r--server/src/com/vaadin/data/DataGenerator.java49
-rw-r--r--server/src/com/vaadin/data/RpcDataProviderExtension.java220
-rw-r--r--server/src/com/vaadin/ui/Grid.java147
-rw-r--r--server/tests/src/com/vaadin/tests/server/renderer/RendererTest.java26
-rw-r--r--shared/src/com/vaadin/shared/ui/grid/GridState.java5
6 files changed, 281 insertions, 199 deletions
diff --git a/client/src/com/vaadin/client/connectors/GridConnector.java b/client/src/com/vaadin/client/connectors/GridConnector.java
index 052d8ee368..bee9cedc43 100644
--- a/client/src/com/vaadin/client/connectors/GridConnector.java
+++ b/client/src/com/vaadin/client/connectors/GridConnector.java
@@ -38,7 +38,6 @@ import com.vaadin.client.ComponentConnector;
import com.vaadin.client.ConnectorHierarchyChangeEvent;
import com.vaadin.client.DeferredWorker;
import com.vaadin.client.MouseEventDetailsBuilder;
-import com.vaadin.client.annotations.OnStateChange;
import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.connectors.RpcDataSourceConnector.DetailsListener;
import com.vaadin.client.connectors.RpcDataSourceConnector.RpcDataSource;
@@ -119,8 +118,8 @@ import elemental.json.JsonValue;
public class GridConnector extends AbstractHasComponentsConnector implements
SimpleManagedLayout, DeferredWorker {
- private static final class CustomCellStyleGenerator implements
- CellStyleGenerator<JsonObject> {
+ private static final class CustomStyleGenerator implements
+ CellStyleGenerator<JsonObject>, RowStyleGenerator<JsonObject> {
@Override
public String getStyle(CellReference<JsonObject> cellReference) {
JsonObject row = cellReference.getRow();
@@ -146,10 +145,6 @@ public class GridConnector extends AbstractHasComponentsConnector implements
}
}
- }
-
- private static final class CustomRowStyleGenerator implements
- RowStyleGenerator<JsonObject> {
@Override
public String getStyle(RowReference<JsonObject> rowReference) {
JsonObject row = rowReference.getRow();
@@ -159,7 +154,6 @@ public class GridConnector extends AbstractHasComponentsConnector implements
return null;
}
}
-
}
/**
@@ -734,6 +728,7 @@ public class GridConnector extends AbstractHasComponentsConnector implements
private String lastKnownTheme = null;
private final CustomDetailsGenerator customDetailsGenerator = new CustomDetailsGenerator();
+ private final CustomStyleGenerator styleGenerator = new CustomStyleGenerator();
private final DetailsConnectorFetcher detailsConnectorFetcher = new DetailsConnectorFetcher(
getRpcProxy(GridServerRpc.class));
@@ -873,6 +868,10 @@ public class GridConnector extends AbstractHasComponentsConnector implements
getWidget().addBodyClickHandler(itemClickHandler);
getWidget().addBodyDoubleClickHandler(itemClickHandler);
+ /* Style Generators */
+ getWidget().setCellStyleGenerator(styleGenerator);
+ getWidget().setRowStyleGenerator(styleGenerator);
+
getWidget().addSortHandler(new SortHandler<JsonObject>() {
@Override
public void sort(SortEvent<JsonObject> event) {
@@ -1289,24 +1288,6 @@ public class GridConnector extends AbstractHasComponentsConnector implements
}
}
- @OnStateChange("hasCellStyleGenerator")
- private void onCellStyleGeneratorChange() {
- if (getState().hasCellStyleGenerator) {
- getWidget().setCellStyleGenerator(new CustomCellStyleGenerator());
- } else {
- getWidget().setCellStyleGenerator(null);
- }
- }
-
- @OnStateChange("hasRowStyleGenerator")
- private void onRowStyleGeneratorChange() {
- if (getState().hasRowStyleGenerator) {
- getWidget().setRowStyleGenerator(new CustomRowStyleGenerator());
- } else {
- getWidget().setRowStyleGenerator(null);
- }
- }
-
private void updateSelectionFromState() {
boolean changed = false;
diff --git a/server/src/com/vaadin/data/DataGenerator.java b/server/src/com/vaadin/data/DataGenerator.java
new file mode 100644
index 0000000000..f025623a3e
--- /dev/null
+++ b/server/src/com/vaadin/data/DataGenerator.java
@@ -0,0 +1,49 @@
+/*
+ * 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.data;
+
+import java.io.Serializable;
+
+import com.vaadin.ui.Grid.AbstractGridExtension;
+import com.vaadin.ui.Grid.AbstractRenderer;
+
+import elemental.json.JsonObject;
+
+/**
+ * Interface for {@link AbstractGridExtension}s that allows adding data to row
+ * objects being sent to client by the {@link RpcDataProviderExtension}.
+ * <p>
+ * {@link AbstractRenderer} implements this interface to provide encoded data to
+ * client for {@link Renderer}s automatically.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public interface DataGenerator extends Serializable {
+
+ /**
+ * Adds data to row object for given item and item id being sent to client.
+ *
+ * @param itemId
+ * item id of item
+ * @param item
+ * item being sent to client
+ * @param rowData
+ * row object being sent to client
+ */
+ public void generateData(Object itemId, Item item, JsonObject rowData);
+
+}
diff --git a/server/src/com/vaadin/data/RpcDataProviderExtension.java b/server/src/com/vaadin/data/RpcDataProviderExtension.java
index 9d18736ba8..71b597ff1d 100644
--- a/server/src/com/vaadin/data/RpcDataProviderExtension.java
+++ b/server/src/com/vaadin/data/RpcDataProviderExtension.java
@@ -23,11 +23,9 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
-import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
-import java.util.logging.Logger;
import com.google.gwt.thirdparty.guava.common.collect.BiMap;
import com.google.gwt.thirdparty.guava.common.collect.HashBiMap;
@@ -43,10 +41,8 @@ import com.vaadin.data.Container.ItemSetChangeNotifier;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.data.Property.ValueChangeNotifier;
-import com.vaadin.data.util.converter.Converter;
import com.vaadin.server.AbstractExtension;
import com.vaadin.server.ClientConnector;
-import com.vaadin.server.KeyMapper;
import com.vaadin.shared.data.DataProviderRpc;
import com.vaadin.shared.data.DataRequestRpc;
import com.vaadin.shared.ui.grid.DetailsConnectorChange;
@@ -56,13 +52,9 @@ import com.vaadin.shared.ui.grid.Range;
import com.vaadin.shared.util.SharedUtil;
import com.vaadin.ui.Component;
import com.vaadin.ui.Grid;
-import com.vaadin.ui.Grid.CellReference;
-import com.vaadin.ui.Grid.CellStyleGenerator;
import com.vaadin.ui.Grid.Column;
import com.vaadin.ui.Grid.DetailsGenerator;
import com.vaadin.ui.Grid.RowReference;
-import com.vaadin.ui.Grid.RowStyleGenerator;
-import com.vaadin.ui.renderers.Renderer;
import elemental.json.Json;
import elemental.json.JsonArray;
@@ -93,7 +85,7 @@ public class RpcDataProviderExtension extends AbstractExtension {
* itemId &lrarr; key mapping is not needed anymore. In other words, this
* doesn't leak memory.
*/
- public class DataProviderKeyMapper implements Serializable {
+ public class DataProviderKeyMapper implements Serializable, DataGenerator {
private final BiMap<Object, String> itemIdToKey = HashBiMap.create();
private Set<Object> pinnedItemIds = new HashSet<Object>();
private long rollingIndex = 0;
@@ -125,7 +117,7 @@ public class RpcDataProviderExtension extends AbstractExtension {
for (Object itemId : itemSet) {
itemIdToKey.put(itemId, getKey(itemId));
- if (visibleDetails.contains(itemId)) {
+ if (detailComponentManager.visibleDetails.contains(itemId)) {
detailComponentManager.createDetails(itemId,
indexOf(itemId));
}
@@ -280,6 +272,16 @@ public class RpcDataProviderExtension extends AbstractExtension {
public boolean isPinned(Object itemId) {
return pinnedItemIds.contains(itemId);
}
+
+ /**
+ * {@inheritDoc}
+ *
+ * @since
+ */
+ @Override
+ public void generateData(Object itemId, Item item, JsonObject rowData) {
+ rowData.put(GridState.JSONKEY_ROWKEY, getKey(itemId));
+ }
}
/**
@@ -601,7 +603,7 @@ public class RpcDataProviderExtension extends AbstractExtension {
* @since 7.5.0
* @author Vaadin Ltd
*/
- public static final class DetailComponentManager implements Serializable {
+ public static final class DetailComponentManager implements DataGenerator {
/**
* This map represents all the components that have been requested for
* each item id.
@@ -649,6 +651,12 @@ public class RpcDataProviderExtension extends AbstractExtension {
*/
private final Map<Object, Integer> emptyDetails = Maps.newHashMap();
+ /**
+ * This map represents all the details that are user-defined as visible.
+ * This does not reflect the status in the DOM.
+ */
+ private Set<Object> visibleDetails = new HashSet<Object>();
+
private Grid grid;
/**
@@ -856,6 +864,18 @@ public class RpcDataProviderExtension extends AbstractExtension {
}
this.grid = grid;
}
+
+ /**
+ * {@inheritDoc}
+ *
+ * @since
+ */
+ @Override
+ public void generateData(Object itemId, Item item, JsonObject rowData) {
+ if (visibleDetails.contains(itemId)) {
+ rowData.put(GridState.JSONKEY_DETAILS_VISIBLE, true);
+ }
+ }
}
private final Indexed container;
@@ -939,14 +959,9 @@ public class RpcDataProviderExtension extends AbstractExtension {
private final DataProviderKeyMapper keyMapper = new DataProviderKeyMapper();
- private KeyMapper<Object> columnKeys;
-
/** RpcDataProvider should send the current cache again. */
private boolean refreshCache = false;
- private RowReference rowReference;
- private CellReference cellReference;
-
/** Set of updated item ids */
private Set<Object> updatedItemIds = new LinkedHashSet<Object>();
@@ -959,14 +974,10 @@ public class RpcDataProviderExtension extends AbstractExtension {
/** Size possibly changed with a bare ItemSetChangeEvent */
private boolean bareItemSetTriggeredSizeChange = false;
- /**
- * This map represents all the details that are user-defined as visible.
- * This does not reflect the status in the DOM.
- */
- private Set<Object> visibleDetails = new HashSet<Object>();
-
private final DetailComponentManager detailComponentManager = new DetailComponentManager();
+ private Set<DataGenerator> dataGenerators = new LinkedHashSet<DataGenerator>();
+
/**
* Creates a new data provider using the given container.
*
@@ -1006,6 +1017,8 @@ public class RpcDataProviderExtension extends AbstractExtension {
.addItemSetChangeListener(itemListener);
}
+ addDataGenerator(keyMapper);
+ addDataGenerator(detailComponentManager);
}
/**
@@ -1090,73 +1103,14 @@ public class RpcDataProviderExtension extends AbstractExtension {
private JsonValue getRowData(Collection<Column> columns, Object itemId) {
Item item = container.getItem(itemId);
- JsonObject rowData = Json.createObject();
-
- Grid grid = getGrid();
-
- for (Column column : columns) {
- Object propertyId = column.getPropertyId();
-
- Object propertyValue = item.getItemProperty(propertyId).getValue();
- JsonValue encodedValue = encodeValue(propertyValue,
- column.getRenderer(), column.getConverter(),
- grid.getLocale());
-
- rowData.put(columnKeys.key(propertyId), encodedValue);
- }
-
final JsonObject rowObject = Json.createObject();
- rowObject.put(GridState.JSONKEY_DATA, rowData);
- rowObject.put(GridState.JSONKEY_ROWKEY, keyMapper.getKey(itemId));
-
- if (visibleDetails.contains(itemId)) {
- rowObject.put(GridState.JSONKEY_DETAILS_VISIBLE, true);
- }
-
- rowReference.set(itemId);
-
- CellStyleGenerator cellStyleGenerator = grid.getCellStyleGenerator();
- if (cellStyleGenerator != null) {
- setGeneratedCellStyles(cellStyleGenerator, rowObject, columns);
- }
- RowStyleGenerator rowStyleGenerator = grid.getRowStyleGenerator();
- if (rowStyleGenerator != null) {
- setGeneratedRowStyles(rowStyleGenerator, rowObject);
+ for (DataGenerator dg : dataGenerators) {
+ dg.generateData(itemId, item, rowObject);
}
return rowObject;
}
- private void setGeneratedCellStyles(CellStyleGenerator generator,
- JsonObject rowObject, Collection<Column> columns) {
- JsonObject cellStyles = null;
- for (Column column : columns) {
- Object propertyId = column.getPropertyId();
- cellReference.set(propertyId);
- String style = generator.getStyle(cellReference);
- if (style != null && !style.isEmpty()) {
- if (cellStyles == null) {
- cellStyles = Json.createObject();
- }
-
- String columnKey = columnKeys.key(propertyId);
- cellStyles.put(columnKey, style);
- }
- }
- if (cellStyles != null) {
- rowObject.put(GridState.JSONKEY_CELLSTYLES, cellStyles);
- }
-
- }
-
- private void setGeneratedRowStyles(RowStyleGenerator generator,
- JsonObject rowObject) {
- String rowStyle = generator.getStyle(rowReference);
- if (rowStyle != null && !rowStyle.isEmpty()) {
- rowObject.put(GridState.JSONKEY_ROWSTYLE, rowStyle);
- }
- }
-
/**
* Makes the data source available to the given {@link Grid} component.
*
@@ -1165,13 +1119,38 @@ public class RpcDataProviderExtension extends AbstractExtension {
* @param columnKeys
* the key mapper for columns
*/
- public void extend(Grid component, KeyMapper<Object> columnKeys) {
- this.columnKeys = columnKeys;
+ public void extend(Grid component) {
detailComponentManager.setGrid(component);
super.extend(component);
}
/**
+ * Adds a {@link DataGenerator} for this {@code RpcDataProviderExtension}.
+ * DataGenerators are called when sending row data to client. If given
+ * DataGenerator is already added, this method does nothing.
+ *
+ * @since
+ * @param generator
+ * generator to add
+ */
+ public void addDataGenerator(DataGenerator generator) {
+ dataGenerators.add(generator);
+ }
+
+ /**
+ * Removes a {@link DataGenerator} from this
+ * {@code RpcDataProviderExtension}. If given DataGenerator is not added to
+ * this data provider, this method does nothing.
+ *
+ * @since
+ * @param generator
+ * generator to remove
+ */
+ public void removeDataGenerator(DataGenerator generator) {
+ dataGenerators.remove(generator);
+ }
+
+ /**
* Informs the client side that new rows have been inserted into the data
* source.
*
@@ -1281,11 +1260,7 @@ public class RpcDataProviderExtension extends AbstractExtension {
.removeItemSetChangeListener(itemListener);
}
- } else if (parent instanceof Grid) {
- Grid grid = (Grid) parent;
- rowReference = new RowReference(grid);
- cellReference = new CellReference(rowReference);
- } else {
+ } else if (!(parent instanceof Grid)) {
throw new IllegalStateException(
"Grid is the only accepted parent type");
}
@@ -1322,62 +1297,6 @@ public class RpcDataProviderExtension extends AbstractExtension {
}
/**
- * Converts and encodes the given data model property value using the given
- * converter and renderer. This method is public only for testing purposes.
- *
- * @param renderer
- * the renderer to use
- * @param converter
- * the converter to use
- * @param modelValue
- * the value to convert and encode
- * @param locale
- * the locale to use in conversion
- * @return an encoded value ready to be sent to the client
- */
- public static <T> JsonValue encodeValue(Object modelValue,
- Renderer<T> renderer, Converter<?, ?> converter, Locale locale) {
- Class<T> presentationType = renderer.getPresentationType();
- T presentationValue;
-
- if (converter == null) {
- try {
- presentationValue = presentationType.cast(modelValue);
- } catch (ClassCastException e) {
- if (presentationType == String.class) {
- // If there is no converter, just fallback to using
- // toString().
- // modelValue can't be null as Class.cast(null) will always
- // succeed
- presentationValue = (T) modelValue.toString();
- } else {
- throw new Converter.ConversionException(
- "Unable to convert value of type "
- + modelValue.getClass().getName()
- + " to presentation type "
- + presentationType.getName()
- + ". No converter is set and the types are not compatible.");
- }
- }
- } else {
- assert presentationType.isAssignableFrom(converter
- .getPresentationType());
- @SuppressWarnings("unchecked")
- Converter<T, Object> safeConverter = (Converter<T, Object>) converter;
- presentationValue = safeConverter.convertToPresentation(modelValue,
- safeConverter.getPresentationType(), locale);
- }
-
- JsonValue encodedValue = renderer.encode(presentationValue);
-
- return encodedValue;
- }
-
- private static Logger getLogger() {
- return Logger.getLogger(RpcDataProviderExtension.class.getName());
- }
-
- /**
* Marks a row's details to be visible or hidden.
* <p>
* If that row is currently in the client side's cache, this information
@@ -1394,7 +1313,7 @@ public class RpcDataProviderExtension extends AbstractExtension {
final boolean modified;
if (visible) {
- modified = visibleDetails.add(itemId);
+ modified = detailComponentManager.visibleDetails.add(itemId);
/*
* We don't want to create the component here, since the component
@@ -1405,7 +1324,7 @@ public class RpcDataProviderExtension extends AbstractExtension {
*/
} else {
- modified = visibleDetails.remove(itemId);
+ modified = detailComponentManager.visibleDetails.remove(itemId);
/*
* Here we can try to destroy the component no matter what. The
@@ -1435,7 +1354,7 @@ public class RpcDataProviderExtension extends AbstractExtension {
* visible in the DOM
*/
public boolean isDetailsVisible(Object itemId) {
- return visibleDetails.contains(itemId);
+ return detailComponentManager.visibleDetails.contains(itemId);
}
/**
@@ -1444,7 +1363,8 @@ public class RpcDataProviderExtension extends AbstractExtension {
* @since 7.5.0
*/
public void refreshDetails() {
- for (Object itemId : ImmutableSet.copyOf(visibleDetails)) {
+ for (Object itemId : ImmutableSet
+ .copyOf(detailComponentManager.visibleDetails)) {
detailComponentManager.refresh(itemId);
}
}
diff --git a/server/src/com/vaadin/ui/Grid.java b/server/src/com/vaadin/ui/Grid.java
index f7d49e6419..af89064411 100644
--- a/server/src/com/vaadin/ui/Grid.java
+++ b/server/src/com/vaadin/ui/Grid.java
@@ -31,6 +31,7 @@ import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
@@ -52,6 +53,7 @@ import com.vaadin.data.Container.PropertySetChangeEvent;
import com.vaadin.data.Container.PropertySetChangeListener;
import com.vaadin.data.Container.PropertySetChangeNotifier;
import com.vaadin.data.Container.Sortable;
+import com.vaadin.data.DataGenerator;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.RpcDataProviderExtension;
@@ -1548,6 +1550,60 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
}
/**
+ * Class for generating all row and cell related data for the essential
+ * parts of Grid.
+ */
+ private class RowDataGenerator implements DataGenerator {
+
+ @Override
+ public void generateData(Object itemId, Item item, JsonObject rowData) {
+ RowReference r = new RowReference(Grid.this);
+ r.set(itemId);
+
+ if (rowStyleGenerator != null) {
+ String style = rowStyleGenerator.getStyle(r);
+ if (style != null && !style.isEmpty()) {
+ rowData.put(GridState.JSONKEY_ROWSTYLE, style);
+ }
+ }
+
+ JsonObject cellStyles = Json.createObject();
+ JsonObject cellData = Json.createObject();
+ for (Column column : getColumns()) {
+ Object propertyId = column.getPropertyId();
+ String columnId = columnKeys.key(propertyId);
+
+ cellData.put(columnId, getRendererData(column, item));
+
+ if (cellStyleGenerator != null) {
+ CellReference c = new CellReference(r);
+ c.set(propertyId);
+
+ String style = cellStyleGenerator.getStyle(c);
+ if (style != null && !style.isEmpty()) {
+ cellStyles.put(columnId, style);
+ }
+ }
+ }
+
+ if (cellStyleGenerator != null && cellStyles.keys().length > 0) {
+ rowData.put(GridState.JSONKEY_CELLSTYLES, cellStyles);
+ }
+ rowData.put(GridState.JSONKEY_DATA, cellData);
+ }
+
+ private JsonValue getRendererData(Column column, Item item) {
+ Converter<?, ?> converter = column.getConverter();
+ Object propertyId = column.getPropertyId();
+ Object modelValue = item.getItemProperty(propertyId).getValue();
+ Renderer<?> renderer = column.getRenderer();
+
+ return AbstractRenderer.encodeValue(modelValue, renderer,
+ converter, getLocale());
+ }
+ }
+
+ /**
* Abstract base class for Grid header and footer sections.
*
* @param <ROWTYPE>
@@ -3462,10 +3518,67 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
return JsonCodec.encode(value, null, type,
getUI().getConnectorTracker()).getEncodedValue();
}
+
+ /**
+ * Converts and encodes the given data model property value using the
+ * given converter and renderer. This method is public only for testing
+ * purposes.
+ *
+ * @param renderer
+ * the renderer to use
+ * @param converter
+ * the converter to use
+ * @param modelValue
+ * the value to convert and encode
+ * @param locale
+ * the locale to use in conversion
+ * @return an encoded value ready to be sent to the client
+ */
+ public static <T> JsonValue encodeValue(Object modelValue,
+ Renderer<T> renderer, Converter<?, ?> converter, Locale locale) {
+ Class<T> presentationType = renderer.getPresentationType();
+ T presentationValue;
+
+ if (converter == null) {
+ try {
+ presentationValue = presentationType.cast(modelValue);
+ } catch (ClassCastException e) {
+ if (presentationType == String.class) {
+ // If there is no converter, just fallback to using
+ // toString(). modelValue can't be null as
+ // Class.cast(null) will always succeed
+ presentationValue = (T) modelValue.toString();
+ } else {
+ throw new Converter.ConversionException(
+ "Unable to convert value of type "
+ + modelValue.getClass().getName()
+ + " to presentation type "
+ + presentationType.getName()
+ + ". No converter is set and the types are not compatible.");
+ }
+ }
+ } else {
+ assert presentationType.isAssignableFrom(converter
+ .getPresentationType());
+ @SuppressWarnings("unchecked")
+ Converter<T, Object> safeConverter = (Converter<T, Object>) converter;
+ presentationValue = safeConverter
+ .convertToPresentation(modelValue,
+ safeConverter.getPresentationType(), locale);
+ }
+
+ JsonValue encodedValue = renderer.encode(presentationValue);
+
+ return encodedValue;
+ }
}
/**
* An abstract base class for server-side Grid extensions.
+ * <p>
+ * Note: If the extension is an instance of {@link DataGenerator} it will
+ * automatically register itself to {@link RpcDataProviderExtension} of
+ * extended Grid. On remove this registration is automatically removed.
*
* @since 7.5
*/
@@ -3490,6 +3603,26 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
extend(grid);
}
+ @Override
+ protected void extend(AbstractClientConnector target) {
+ super.extend(target);
+
+ if (this instanceof DataGenerator) {
+ getParentGrid().datasourceExtension
+ .addDataGenerator((DataGenerator) this);
+ }
+ }
+
+ @Override
+ public void remove() {
+ if (this instanceof DataGenerator) {
+ getParentGrid().datasourceExtension
+ .removeDataGenerator((DataGenerator) this);
+ }
+
+ super.remove();
+ }
+
/**
* Gets the item id for a row key.
* <p>
@@ -3531,9 +3664,14 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
if (getParent() instanceof Grid) {
Grid grid = (Grid) getParent();
return grid;
+ } else if (getParent() == null) {
+ throw new IllegalStateException(
+ "Renderer is not attached to any parent");
} else {
throw new IllegalStateException(
- "Renderers can be used only with Grid");
+ "Renderers can be used only with Grid. Extended "
+ + getParent().getClass().getSimpleName()
+ + " instead");
}
}
}
@@ -4153,7 +4291,8 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
}
datasourceExtension = new RpcDataProviderExtension(container);
- datasourceExtension.extend(this, columnKeys);
+ datasourceExtension.extend(this);
+ datasourceExtension.addDataGenerator(new RowDataGenerator());
detailComponentManager = datasourceExtension
.getDetailComponentManager();
@@ -5620,8 +5759,6 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
*/
public void setCellStyleGenerator(CellStyleGenerator cellStyleGenerator) {
this.cellStyleGenerator = cellStyleGenerator;
- getState().hasCellStyleGenerator = (cellStyleGenerator != null);
-
datasourceExtension.refreshCache();
}
@@ -5644,8 +5781,6 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
*/
public void setRowStyleGenerator(RowStyleGenerator rowStyleGenerator) {
this.rowStyleGenerator = rowStyleGenerator;
- getState().hasRowStyleGenerator = (rowStyleGenerator != null);
-
datasourceExtension.refreshCache();
}
diff --git a/server/tests/src/com/vaadin/tests/server/renderer/RendererTest.java b/server/tests/src/com/vaadin/tests/server/renderer/RendererTest.java
index eb07fae07f..cea8df0ba6 100644
--- a/server/tests/src/com/vaadin/tests/server/renderer/RendererTest.java
+++ b/server/tests/src/com/vaadin/tests/server/renderer/RendererTest.java
@@ -15,8 +15,17 @@
*/
package com.vaadin.tests.server.renderer;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+
+import java.util.Date;
+import java.util.Locale;
+
+import org.junit.Before;
+import org.junit.Test;
+
import com.vaadin.data.Item;
-import com.vaadin.data.RpcDataProviderExtension;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.data.util.converter.Converter;
import com.vaadin.data.util.converter.StringToIntegerConverter;
@@ -24,22 +33,15 @@ import com.vaadin.server.VaadinSession;
import com.vaadin.tests.server.component.grid.TestGrid;
import com.vaadin.tests.util.AlwaysLockedVaadinSession;
import com.vaadin.ui.Grid;
+import com.vaadin.ui.Grid.AbstractRenderer;
import com.vaadin.ui.Grid.Column;
import com.vaadin.ui.renderers.ButtonRenderer;
import com.vaadin.ui.renderers.DateRenderer;
import com.vaadin.ui.renderers.HtmlRenderer;
import com.vaadin.ui.renderers.NumberRenderer;
import com.vaadin.ui.renderers.TextRenderer;
-import elemental.json.JsonValue;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.Date;
-import java.util.Locale;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
+import elemental.json.JsonValue;
public class RendererTest {
@@ -259,7 +261,7 @@ public class RendererTest {
}
private JsonValue render(Column column, Object value) {
- return RpcDataProviderExtension.encodeValue(value,
- column.getRenderer(), column.getConverter(), grid.getLocale());
+ return AbstractRenderer.encodeValue(value, column.getRenderer(),
+ column.getConverter(), grid.getLocale());
}
}
diff --git a/shared/src/com/vaadin/shared/ui/grid/GridState.java b/shared/src/com/vaadin/shared/ui/grid/GridState.java
index c4121cbf45..c455ffe23b 100644
--- a/shared/src/com/vaadin/shared/ui/grid/GridState.java
+++ b/shared/src/com/vaadin/shared/ui/grid/GridState.java
@@ -160,11 +160,6 @@ public class GridState extends TabIndexState {
@DelegateToWidget
public boolean editorBuffered = true;
- /** Whether row data might contain generated row styles */
- public boolean hasRowStyleGenerator;
- /** Whether row data might contain generated cell styles */
- public boolean hasCellStyleGenerator;
-
/** The caption for the save button in the editor */
@DelegateToWidget
public String editorSaveCaption = GridConstants.DEFAULT_SAVE_CAPTION;