Browse Source

Add ValueProvider interface, use where appropriate

tags/8.0.0.alpha10
Aleksi Hietanen 7 years ago
parent
commit
334fd4bcef

+ 2
- 2
server/src/main/java/com/vaadin/data/BeanBinder.java View File

* @throws IllegalArgumentException * @throws IllegalArgumentException
* if the property has no accessible getter * if the property has no accessible getter
* *
* @see BindingBuilder#bind(SerializableFunction,
* @see BindingBuilder#bind(ValueProvider,
* SerializableBiConsumer) * SerializableBiConsumer)
*/ */
public Binding<BEAN, TARGET> bind(String propertyName); public Binding<BEAN, TARGET> bind(String propertyName);
* @throws IllegalArgumentException * @throws IllegalArgumentException
* if the property has no accessible getter * if the property has no accessible getter
* *
* @see #bind(HasValue, SerializableFunction, SerializableBiConsumer)
* @see #bind(HasValue, ValueProvider, SerializableBiConsumer)
*/ */
public <FIELDVALUE> Binding<BEAN, FIELDVALUE> bind( public <FIELDVALUE> Binding<BEAN, FIELDVALUE> bind(
HasValue<FIELDVALUE> field, String propertyName) { HasValue<FIELDVALUE> field, String propertyName) {

+ 9
- 9
server/src/main/java/com/vaadin/data/Binder.java View File

* if {@code bind} has already been called on this binding * if {@code bind} has already been called on this binding
*/ */
public Binding<BEAN, TARGET> bind( public Binding<BEAN, TARGET> bind(
SerializableFunction<BEAN, TARGET> getter,
ValueProvider<BEAN, TARGET> getter,
com.vaadin.server.SerializableBiConsumer<BEAN, TARGET> setter); com.vaadin.server.SerializableBiConsumer<BEAN, TARGET> setter);


/** /**
* which must match the current target data type of the binding, and a * which must match the current target data type of the binding, and a
* model type, which can be any data type and becomes the new target * model type, which can be any data type and becomes the new target
* type of the binding. When invoking * type of the binding. When invoking
* {@link #bind(SerializableFunction, SerializableBiConsumer)}, the
* {@link #bind(ValueProvider, SerializableBiConsumer)}, the
* target type of the binding must match the getter/setter types. * target type of the binding must match the getter/setter types.
* <p> * <p>
* For instance, a {@code TextField} can be bound to an integer-typed * For instance, a {@code TextField} can be bound to an integer-typed
* type, which must match the current target data type of the binding, * type, which must match the current target data type of the binding,
* and a model type, which can be any data type and becomes the new * and a model type, which can be any data type and becomes the new
* target type of the binding. When invoking * target type of the binding. When invoking
* {@link #bind(SerializableFunction, SerializableBiConsumer)}, the
* {@link #bind(ValueProvider, SerializableBiConsumer)}, the
* target type of the binding must match the getter/setter types. * target type of the binding must match the getter/setter types.
* <p> * <p>
* For instance, a {@code TextField} can be bound to an integer-typed * For instance, a {@code TextField} can be bound to an integer-typed
* type, which must match the current target data type of the binding, * type, which must match the current target data type of the binding,
* and a model type, which can be any data type and becomes the new * and a model type, which can be any data type and becomes the new
* target type of the binding. When invoking * target type of the binding. When invoking
* {@link #bind(SerializableFunction, SerializableBiConsumer)}, the
* {@link #bind(ValueProvider, SerializableBiConsumer)}, the
* target type of the binding must match the getter/setter types. * target type of the binding must match the getter/setter types.
* <p> * <p>
* For instance, a {@code TextField} can be bound to an integer-typed * For instance, a {@code TextField} can be bound to an integer-typed


@Override @Override
public Binding<BEAN, TARGET> bind( public Binding<BEAN, TARGET> bind(
SerializableFunction<BEAN, TARGET> getter,
ValueProvider<BEAN, TARGET> getter,
SerializableBiConsumer<BEAN, TARGET> setter) { SerializableBiConsumer<BEAN, TARGET> setter) {
checkUnbound(); checkUnbound();
Objects.requireNonNull(getter, "getter cannot be null"); Objects.requireNonNull(getter, "getter cannot be null");
/** /**
* Creates a new binding for the given field. The returned builder may be * Creates a new binding for the given field. The returned builder may be
* further configured before invoking * further configured before invoking
* {@link BindingBuilder#bind(SerializableFunction, SerializableBiConsumer)}
* {@link BindingBuilder#bind(ValueProvider, SerializableBiConsumer)}
* which completes the binding. Until {@code Binding.bind} is called, the * which completes the binding. Until {@code Binding.bind} is called, the
* binding has no effect. * binding has no effect.
* <p> * <p>
* the field to be bound, not null * the field to be bound, not null
* @return the new binding * @return the new binding
* *
* @see #bind(HasValue, SerializableFunction, SerializableBiConsumer)
* @see #bind(HasValue, ValueProvider, SerializableBiConsumer)
*/ */
public <FIELDVALUE> BindingBuilder<BEAN, FIELDVALUE> forField( public <FIELDVALUE> BindingBuilder<BEAN, FIELDVALUE> forField(
HasValue<FIELDVALUE> field) { HasValue<FIELDVALUE> field) {
*/ */
public <FIELDVALUE> Binding<BEAN, FIELDVALUE> bind( public <FIELDVALUE> Binding<BEAN, FIELDVALUE> bind(
HasValue<FIELDVALUE> field, HasValue<FIELDVALUE> field,
SerializableFunction<BEAN, FIELDVALUE> getter,
ValueProvider<BEAN, FIELDVALUE> getter,
SerializableBiConsumer<BEAN, FIELDVALUE> setter) { SerializableBiConsumer<BEAN, FIELDVALUE> setter) {
return forField(field).bind(getter, setter); return forField(field).bind(getter, setter);
} }
* <li>{@link #setBean(Object)} is called * <li>{@link #setBean(Object)} is called
* <li>{@link #removeBean()} is called * <li>{@link #removeBean()} is called
* <li> * <li>
* {@link BindingBuilder#bind(SerializableFunction, SerializableBiConsumer)}
* {@link BindingBuilder#bind(ValueProvider, SerializableBiConsumer)}
* is called * is called
* <li>{@link Binder#validate()} or {@link Binding#validate()} is called * <li>{@link Binder#validate()} or {@link Binding#validate()} is called
* </ul> * </ul>

+ 1
- 1
server/src/main/java/com/vaadin/data/HasValue.java View File

* values. Specific implementations might not support this. * values. Specific implementations might not support this.
* *
* @return empty value * @return empty value
* @see Binder#bind(HasValue, java.util.function.Function, BiConsumer)
* @see Binder#bind(HasValue, ValueProvider, BiConsumer)
*/ */
public default V getEmptyValue() { public default V getEmptyValue() {
return null; return null;

+ 1
- 2
server/src/main/java/com/vaadin/data/StatusChangeEvent.java View File

import com.vaadin.data.Binder.Binding; import com.vaadin.data.Binder.Binding;
import com.vaadin.data.Binder.BindingBuilder; import com.vaadin.data.Binder.BindingBuilder;
import com.vaadin.server.SerializableBiConsumer; import com.vaadin.server.SerializableBiConsumer;
import com.vaadin.server.SerializableFunction;


/** /**
* Binder status change event. * Binder status change event.
* <li>{@link Binder#readBean(Object)} is called * <li>{@link Binder#readBean(Object)} is called
* <li>{@link Binder#setBean(Object)} is called * <li>{@link Binder#setBean(Object)} is called
* <li>{@link Binder#removeBean()} is called * <li>{@link Binder#removeBean()} is called
* <li>{@link BindingBuilder#bind(SerializableFunction, SerializableBiConsumer)}
* <li>{@link BindingBuilder#bind(ValueProvider, SerializableBiConsumer)}
* is called * is called
* <li>{@link Binder#validate()} or {@link Binding#validate()} is called * <li>{@link Binder#validate()} or {@link Binding#validate()} is called
* </ul> * </ul>

+ 59
- 0
server/src/main/java/com/vaadin/data/ValueProvider.java View File

/*
* Copyright 2000-2016 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 com.vaadin.server.SerializableFunction;

/**
* A callback interface for providing values from a given source.
* <p>
* For example this interface can be implemented to simply extract a value with
* a getter, or to create a composite value based on the fields of the source
* object.
*
* @author Vaadin Ltd.
* @since 8.0
*
* @param <SOURCE>
* the type of the object used to provide the value
* @param <TARGET>
* the type of the provided value
*/
@FunctionalInterface
public interface ValueProvider<SOURCE, TARGET>
extends SerializableFunction<SOURCE, TARGET> {

/**
* Returns a value provider that always returns its input argument.
*
* @param <T>
* the type of the input and output objects to the function
* @return a function that always returns its input argument
*/
public static <T> ValueProvider<T, T> identity() {
return t -> t;
}

/**
* Provides a value from the given source object.
*
* @param source
* the source to retrieve the value from
* @return the value provided by the source
*/
@Override
public TARGET apply(SOURCE source);
}

+ 2
- 2
server/src/main/java/com/vaadin/ui/DeclarativeValueProvider.java View File

import java.util.IdentityHashMap; import java.util.IdentityHashMap;
import java.util.Map; import java.util.Map;


import com.vaadin.server.SerializableFunction;
import com.vaadin.data.ValueProvider;


/** /**
* Value provider class for declarative support. * Value provider class for declarative support.
* @param <T> * @param <T>
* item type * item type
*/ */
class DeclarativeValueProvider<T> implements SerializableFunction<T, String> {
class DeclarativeValueProvider<T> implements ValueProvider<T, String> {


private final Map<T, String> values = new IdentityHashMap<>(); private final Map<T, String> values = new IdentityHashMap<>();



+ 6
- 5
server/src/main/java/com/vaadin/ui/Grid.java View File

import com.vaadin.data.BinderValidationStatus; import com.vaadin.data.BinderValidationStatus;
import com.vaadin.data.Listing; import com.vaadin.data.Listing;
import com.vaadin.data.SelectionModel; import com.vaadin.data.SelectionModel;
import com.vaadin.data.ValueProvider;
import com.vaadin.event.ConnectorEvent; import com.vaadin.event.ConnectorEvent;
import com.vaadin.event.ContextClickEvent; import com.vaadin.event.ContextClickEvent;
import com.vaadin.event.SerializableEventListener; import com.vaadin.event.SerializableEventListener;
* the type of value * the type of value
*/ */
protected Column(String caption, protected Column(String caption,
SerializableFunction<T, ? extends V> valueProvider,
ValueProvider<T, ? extends V> valueProvider,
Renderer<V> renderer) { Renderer<V> renderer) {
Objects.requireNonNull(caption, "Header caption can't be null"); Objects.requireNonNull(caption, "Header caption can't be null");
Objects.requireNonNull(valueProvider, Objects.requireNonNull(valueProvider,
* @see AbstractRenderer * @see AbstractRenderer
*/ */
public <V> Column<T, V> addColumn(String identifier, public <V> Column<T, V> addColumn(String identifier,
SerializableFunction<T, ? extends V> valueProvider,
ValueProvider<T, ? extends V> valueProvider,
AbstractRenderer<? super T, V> renderer) AbstractRenderer<? super T, V> renderer)
throws IllegalArgumentException { throws IllegalArgumentException {
if (columnKeys.containsKey(identifier)) { if (columnKeys.containsKey(identifier)) {
* if the same identifier is used for multiple columns * if the same identifier is used for multiple columns
*/ */
public Column<T, String> addColumn(String identifier, public Column<T, String> addColumn(String identifier,
SerializableFunction<T, String> valueProvider) {
ValueProvider<T, String> valueProvider) {
return addColumn(identifier, valueProvider, new TextRenderer()); return addColumn(identifier, valueProvider, new TextRenderer());
} }


* @return the new column * @return the new column
*/ */
public Column<T, String> addColumn( public Column<T, String> addColumn(
SerializableFunction<T, ?> valueProvider) {
ValueProvider<T, String> valueProvider) {
return addColumn(getGeneratedIdentifier(), return addColumn(getGeneratedIdentifier(),
t -> String.valueOf(valueProvider.apply(t)), t -> String.valueOf(valueProvider.apply(t)),
new TextRenderer()); new TextRenderer());
* @see AbstractRenderer * @see AbstractRenderer
*/ */
public <V> Column<T, V> addColumn( public <V> Column<T, V> addColumn(
SerializableFunction<T, ? extends V> valueProvider,
ValueProvider<T, ? extends V> valueProvider,
AbstractRenderer<? super T, V> renderer) { AbstractRenderer<? super T, V> renderer) {
return addColumn(getGeneratedIdentifier(), valueProvider, renderer); return addColumn(getGeneratedIdentifier(), valueProvider, renderer);
} }

+ 3
- 3
server/src/test/java/com/vaadin/tests/server/component/grid/GridDefaultHeaderTest.java View File

import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;


import com.vaadin.server.SerializableFunction;
import com.vaadin.data.ValueProvider;
import com.vaadin.ui.Grid; import com.vaadin.ui.Grid;
import com.vaadin.ui.Grid.Column; import com.vaadin.ui.Grid.Column;
import com.vaadin.ui.Grid.HeaderRow; import com.vaadin.ui.Grid.HeaderRow;
public void setUp() { public void setUp() {
grid = new Grid<>(); grid = new Grid<>();


column1 = grid.addColumn("First", SerializableFunction.identity());
column2 = grid.addColumn("Second", SerializableFunction.identity());
column1 = grid.addColumn("First", ValueProvider.identity());
column2 = grid.addColumn("Second", ValueProvider.identity());
} }


@Test @Test

+ 3
- 3
server/src/test/java/com/vaadin/tests/server/component/grid/GridHeaderFooterTest.java View File

import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;


import com.vaadin.server.SerializableFunction;
import com.vaadin.data.ValueProvider;
import com.vaadin.ui.Grid; import com.vaadin.ui.Grid;
import com.vaadin.ui.Grid.Column; import com.vaadin.ui.Grid.Column;
import com.vaadin.ui.Grid.HeaderRow; import com.vaadin.ui.Grid.HeaderRow;
@Test @Test
public void addColumn_headerCellAdded() { public void addColumn_headerCellAdded() {
Column<?, ?> column = grid.addColumn("Col", Column<?, ?> column = grid.addColumn("Col",
SerializableFunction.identity());
ValueProvider.identity());


assertNotNull(grid.getHeaderRow(0).getCell(column)); assertNotNull(grid.getHeaderRow(0).getCell(column));
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void removeColumn_headerCellRemoved() { public void removeColumn_headerCellRemoved() {
Column<String, ?> column = grid.addColumn("Col", Column<String, ?> column = grid.addColumn("Col",
SerializableFunction.identity());
ValueProvider.identity());
grid.removeColumn(column); grid.removeColumn(column);


grid.getHeaderRow(0).getCell(column); grid.getHeaderRow(0).getCell(column);

+ 3
- 3
server/src/test/java/com/vaadin/tests/server/component/grid/GridTest.java View File

import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;


import com.vaadin.data.ValueProvider;
import com.vaadin.event.selection.SelectionEvent; import com.vaadin.event.selection.SelectionEvent;
import com.vaadin.server.SerializableFunction;
import com.vaadin.shared.ui.grid.HeightMode; import com.vaadin.shared.ui.grid.HeightMode;
import com.vaadin.ui.Grid; import com.vaadin.ui.Grid;
import com.vaadin.ui.Grid.SelectionMode; import com.vaadin.ui.Grid.SelectionMode;
@Before @Before
public void setUp() { public void setUp() {
grid = new Grid<>(); grid = new Grid<>();
grid.addColumn("foo", SerializableFunction.identity());
grid.addColumn("foo", ValueProvider.identity());
grid.addColumn(String::length, new NumberRenderer()); grid.addColumn(String::length, new NumberRenderer());
grid.addColumn("randomColumnId", SerializableFunction.identity());
grid.addColumn("randomColumnId", ValueProvider.identity());
} }


@Test @Test

+ 2
- 2
uitest/src/main/java/com/vaadin/tests/components/grid/GridApplyFilterWhenScrolledDown.java View File

import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;


import com.vaadin.server.SerializableFunction;
import com.vaadin.data.ValueProvider;
import com.vaadin.server.VaadinRequest; import com.vaadin.server.VaadinRequest;
import com.vaadin.server.data.DataProvider; import com.vaadin.server.data.DataProvider;
import com.vaadin.tests.components.AbstractTestUI; import com.vaadin.tests.components.AbstractTestUI;
protected void setup(VaadinRequest request) { protected void setup(VaadinRequest request) {
Grid<String> grid = new Grid<>(); Grid<String> grid = new Grid<>();


grid.addColumn("Name", SerializableFunction.identity());
grid.addColumn("Name", ValueProvider.identity());


List<String> data = new ArrayList<>(); List<String> data = new ArrayList<>();
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {

Loading…
Cancel
Save