Skip to content

Commit

Permalink
Correct serializable issues and test that components can be serialized
Browse files Browse the repository at this point in the history
Change-Id: Iac8f0f48806c0a7c3030bd406e2e533104f26753
  • Loading branch information
Legioth authored and Denis Anisimov committed Oct 24, 2016
1 parent 51c0978 commit 3f37f89
Show file tree
Hide file tree
Showing 25 changed files with 402 additions and 137 deletions.
21 changes: 11 additions & 10 deletions server/src/main/java/com/vaadin/data/BeanBinder.java
Expand Up @@ -21,12 +21,13 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Predicate;

import com.vaadin.data.util.BeanUtil;
import com.vaadin.data.util.converter.Converter;
import com.vaadin.data.validator.BeanValidator;
import com.vaadin.server.SerializableBiConsumer;
import com.vaadin.server.SerializableFunction;
import com.vaadin.server.SerializablePredicate;
import com.vaadin.util.ReflectTools;

/**
Expand Down Expand Up @@ -63,7 +64,8 @@ public BeanBinding<BEAN, FIELDVALUE, TARGET> withValidator(

@Override
public default BeanBinding<BEAN, FIELDVALUE, TARGET> withValidator(
Predicate<? super TARGET> predicate, String message) {
SerializablePredicate<? super TARGET> predicate,
String message) {
return (BeanBinding<BEAN, FIELDVALUE, TARGET>) Binding.super.withValidator(
predicate, message);
}
Expand All @@ -74,16 +76,16 @@ public <NEWTARGET> BeanBinding<BEAN, FIELDVALUE, NEWTARGET> withConverter(

@Override
public default <NEWTARGET> BeanBinding<BEAN, FIELDVALUE, NEWTARGET> withConverter(
Function<TARGET, NEWTARGET> toModel,
Function<NEWTARGET, TARGET> toPresentation) {
SerializableFunction<TARGET, NEWTARGET> toModel,
SerializableFunction<NEWTARGET, TARGET> toPresentation) {
return (BeanBinding<BEAN, FIELDVALUE, NEWTARGET>) Binding.super.withConverter(
toModel, toPresentation);
}

@Override
public default <NEWTARGET> BeanBinding<BEAN, FIELDVALUE, NEWTARGET> withConverter(
Function<TARGET, NEWTARGET> toModel,
Function<NEWTARGET, TARGET> toPresentation,
SerializableFunction<TARGET, NEWTARGET> toModel,
SerializableFunction<NEWTARGET, TARGET> toPresentation,
String errorMessage) {
return (BeanBinding<BEAN, FIELDVALUE, NEWTARGET>) Binding.super.withConverter(
toModel, toPresentation, errorMessage);
Expand All @@ -110,7 +112,7 @@ public default <NEWTARGET> BeanBinding<BEAN, FIELDVALUE, NEWTARGET> withConverte
* @throws IllegalArgumentException
* if the property has no accessible getter
*
* @see Binding#bind(Function, java.util.function.BiConsumer)
* @see Binding#bind(SerializableFunction, SerializableBiConsumer)
*/
public void bind(String propertyName);
}
Expand Down Expand Up @@ -294,8 +296,7 @@ public <FIELDVALUE> BeanBinding<BEAN, FIELDVALUE, FIELDVALUE> forField(
* @throws IllegalArgumentException
* if the property has no accessible getter
*
* @see #bind(HasValue, java.util.function.Function,
* java.util.function.BiConsumer)
* @see #bind(HasValue, SerializableFunction, SerializableBiConsumer)
*/
public <FIELDVALUE> void bind(HasValue<FIELDVALUE> field,
String propertyName) {
Expand Down
61 changes: 34 additions & 27 deletions server/src/main/java/com/vaadin/data/Binder.java
Expand Up @@ -28,15 +28,16 @@
import java.util.Optional;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import com.vaadin.data.util.converter.Converter;
import com.vaadin.data.util.converter.StringToIntegerConverter;
import com.vaadin.data.util.converter.ValueContext;
import com.vaadin.event.EventRouter;
import com.vaadin.server.ErrorMessage;
import com.vaadin.server.SerializableBiConsumer;
import com.vaadin.server.SerializableFunction;
import com.vaadin.server.SerializablePredicate;
import com.vaadin.server.UserError;
import com.vaadin.shared.Registration;
import com.vaadin.ui.AbstractComponent;
Expand Down Expand Up @@ -139,8 +140,8 @@ public interface Binding<BEAN, FIELDVALUE, TARGET> extends Serializable {
* @throws IllegalStateException
* if {@code bind} has already been called on this binding
*/
public void bind(Function<BEAN, TARGET> getter,
BiConsumer<BEAN, TARGET> setter);
public void bind(SerializableFunction<BEAN, TARGET> getter,
com.vaadin.server.SerializableBiConsumer<BEAN, TARGET> setter);

/**
* Adds a validator to this binding. Validators are applied, in
Expand All @@ -159,14 +160,14 @@ public Binding<BEAN, FIELDVALUE, TARGET> withValidator(

/**
* A convenience method to add a validator to this binding using the
* {@link Validator#from(Predicate, String)} factory method.
* {@link Validator#from(SerializablePredicate, String)} factory method.
* <p>
* Validators are applied, in registration order, when the field value
* is saved to the backing property. If any validator returns a failure,
* the property value is not updated.
*
* @see #withValidator(Validator)
* @see Validator#from(Predicate, String)
* @see Validator#from(SerializablePredicate, String)
*
* @param predicate
* the predicate performing validation, not null
Expand All @@ -177,7 +178,8 @@ public Binding<BEAN, FIELDVALUE, TARGET> withValidator(
* if {@code bind} has already been called
*/
public default Binding<BEAN, FIELDVALUE, TARGET> withValidator(
Predicate<? super TARGET> predicate, String message) {
SerializablePredicate<? super TARGET> predicate,
String message) {
return withValidator(Validator.from(predicate, message));
}

Expand All @@ -189,8 +191,8 @@ public default Binding<BEAN, FIELDVALUE, TARGET> withValidator(
* 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
* type of the binding. When invoking
* {@link #bind(Function, BiConsumer)}, the target type of the binding
* must match the getter/setter types.
* {@link #bind(SerializableFunction, SerializableBiConsumer)}, the
* target type of the binding must match the getter/setter types.
* <p>
* For instance, a {@code TextField} can be bound to an integer-typed
* property using an appropriate converter such as a
Expand All @@ -215,8 +217,8 @@ public <NEWTARGET> Binding<BEAN, FIELDVALUE, NEWTARGET> withConverter(
* 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
* target type of the binding. When invoking
* {@link #bind(Function, BiConsumer)}, the target type of the binding
* must match the getter/setter types.
* {@link #bind(SerializableFunction, SerializableBiConsumer)}, the
* target type of the binding must match the getter/setter types.
* <p>
* For instance, a {@code TextField} can be bound to an integer-typed
* property using appropriate functions such as:
Expand All @@ -235,8 +237,8 @@ public <NEWTARGET> Binding<BEAN, FIELDVALUE, NEWTARGET> withConverter(
* if {@code bind} has already been called
*/
public default <NEWTARGET> Binding<BEAN, FIELDVALUE, NEWTARGET> withConverter(
Function<TARGET, NEWTARGET> toModel,
Function<NEWTARGET, TARGET> toPresentation) {
SerializableFunction<TARGET, NEWTARGET> toModel,
SerializableFunction<NEWTARGET, TARGET> toPresentation) {
return withConverter(Converter.from(toModel, toPresentation,
exception -> exception.getMessage()));
}
Expand All @@ -250,8 +252,8 @@ public default <NEWTARGET> Binding<BEAN, FIELDVALUE, NEWTARGET> withConverter(
* 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
* target type of the binding. When invoking
* {@link #bind(Function, BiConsumer)}, the target type of the binding
* must match the getter/setter types.
* {@link #bind(SerializableFunction, SerializableBiConsumer)}, the
* target type of the binding must match the getter/setter types.
* <p>
* For instance, a {@code TextField} can be bound to an integer-typed
* property using appropriate functions such as:
Expand All @@ -273,8 +275,8 @@ public default <NEWTARGET> Binding<BEAN, FIELDVALUE, NEWTARGET> withConverter(
* if {@code bind} has already been called
*/
public default <NEWTARGET> Binding<BEAN, FIELDVALUE, NEWTARGET> withConverter(
Function<TARGET, NEWTARGET> toModel,
Function<NEWTARGET, TARGET> toPresentation,
SerializableFunction<TARGET, NEWTARGET> toModel,
SerializableFunction<NEWTARGET, TARGET> toPresentation,
String errorMessage) {
return withConverter(Converter.from(toModel, toPresentation,
exception -> errorMessage));
Expand Down Expand Up @@ -411,8 +413,8 @@ protected static class BindingImpl<BEAN, FIELDVALUE, TARGET>
private ValidationStatusHandler statusHandler;
private boolean isStatusHandlerChanged;

private Function<BEAN, TARGET> getter;
private BiConsumer<BEAN, TARGET> setter;
private SerializableFunction<BEAN, TARGET> getter;
private SerializableBiConsumer<BEAN, TARGET> setter;

/**
* Contains all converters and validators chained together in the
Expand Down Expand Up @@ -443,8 +445,8 @@ protected BindingImpl(Binder<BEAN> binder, HasValue<FIELDVALUE> field,
}

@Override
public void bind(Function<BEAN, TARGET> getter,
BiConsumer<BEAN, TARGET> setter) {
public void bind(SerializableFunction<BEAN, TARGET> getter,
SerializableBiConsumer<BEAN, TARGET> setter) {
checkUnbound();
Objects.requireNonNull(getter, "getter cannot be null");

Expand Down Expand Up @@ -717,7 +719,7 @@ public Optional<BEAN> getBean() {

/**
* Creates a new binding for the given field. The returned binding may be
* further configured before invoking
* further configured before invoking <<<<<<< Upstream, based on master
* {@link Binding#bind(Function, BiConsumer) Binding.bind} which completes
* the binding. Until {@code Binding.bind} is called, the binding has no
* effect.
Expand All @@ -727,15 +729,19 @@ public Optional<BEAN> getBean() {
* automatically change {@code null} to a null representation provided by
* {@link HasValue#getEmptyValue()}. This conversion is one-way only, if you
* want to have a two-way mapping back to {@code null}, use
* {@link Binding#withNullRepresentation(Object))}.
* {@link Binding#withNullRepresentation(Object))}. =======
* {@link Binding#bind(SerializableFunction, SerializableBiConsumer)
* Binding.bind} which completes the binding. Until {@code Binding.bind} is
* called, the binding has no effect. >>>>>>> 7d541b5 Correct serializable
* issues and test that components can be serialized
*
* @param <FIELDVALUE>
* the value type of the field
* @param field
* the field to be bound, not null
* @return the new binding
*
* @see #bind(HasValue, Function, BiConsumer)
* @see #bind(HasValue, SerializableFunction, SerializableBiConsumer)
*/
public <FIELDVALUE> Binding<BEAN, FIELDVALUE, FIELDVALUE> forField(
HasValue<FIELDVALUE> field) {
Expand Down Expand Up @@ -803,8 +809,8 @@ public <FIELDVALUE> Binding<BEAN, FIELDVALUE, FIELDVALUE> forField(
* if read-only
*/
public <FIELDVALUE> void bind(HasValue<FIELDVALUE> field,
Function<BEAN, FIELDVALUE> getter,
BiConsumer<BEAN, FIELDVALUE> setter) {
SerializableFunction<BEAN, FIELDVALUE> getter,
SerializableBiConsumer<BEAN, FIELDVALUE> setter) {
forField(field).bind(getter, setter);
}

Expand Down Expand Up @@ -1151,7 +1157,8 @@ public BinderValidationStatusHandler getValidationStatusHandler() {
* <li>{@link #load(Object)} is called
* <li>{@link #bind(Object)} is called
* <li>{@link #unbind(Object)} is called
* <li>{@link Binding#bind(Function, BiConsumer)} is called
* <li>{@link Binding#bind(SerializableFunction, SerializableBiConsumer)} is
* called
* <li>{@link Binder#validate()} or {@link Binding#validate()} is called
* </ul>
*
Expand Down
4 changes: 3 additions & 1 deletion server/src/main/java/com/vaadin/data/Validator.java
Expand Up @@ -21,6 +21,8 @@
import java.util.function.Function;
import java.util.function.Predicate;

import com.vaadin.server.SerializablePredicate;

/**
* A functional interface for validating user input or other potentially invalid
* data. When a validator instance is applied to a value of the corresponding
Expand Down Expand Up @@ -117,7 +119,7 @@ public static <T> Validator<T> alwaysPass() {
* the message returned if validation fails, not null
* @return the new validator using the function
*/
public static <T> Validator<T> from(Predicate<T> guard,
public static <T> Validator<T> from(SerializablePredicate<T> guard,
String errorMessage) {
Objects.requireNonNull(guard, "guard cannot be null");
Objects.requireNonNull(errorMessage, "errorMessage cannot be null");
Expand Down
Expand Up @@ -22,6 +22,7 @@

import com.vaadin.data.Binder.Binding;
import com.vaadin.data.Result;
import com.vaadin.server.SerializableFunction;

/**
* Interface that implements conversion between a model and a presentation type.
Expand Down Expand Up @@ -108,9 +109,10 @@ public static <T> Converter<T, T> identity() {
* @see Result
* @see Function
*/
public static <P, M> Converter<P, M> from(Function<P, M> toModel,
Function<M, P> toPresentation,
Function<Exception, String> onError) {
public static <P, M> Converter<P, M> from(
SerializableFunction<P, M> toModel,
SerializableFunction<M, P> toPresentation,
SerializableFunction<Exception, String> onError) {

return from(val -> Result.of(() -> toModel.apply(val), onError),
toPresentation);
Expand All @@ -131,8 +133,9 @@ public static <P, M> Converter<P, M> from(Function<P, M> toModel,
*
* @see Function
*/
public static <P, M> Converter<P, M> from(Function<P, Result<M>> toModel,
Function<M, P> toPresentation) {
public static <P, M> Converter<P, M> from(
SerializableFunction<P, Result<M>> toModel,
SerializableFunction<M, P> toPresentation) {
return new Converter<P, M>() {

@Override
Expand Down
Expand Up @@ -16,10 +16,10 @@
package com.vaadin.data.validator;

import java.util.Objects;
import java.util.function.Function;

import com.vaadin.data.Result;
import com.vaadin.data.Validator;
import com.vaadin.server.SerializableFunction;

/**
* An abstract base class for typed validators.
Expand All @@ -31,7 +31,7 @@
*/
public abstract class AbstractValidator<T> implements Validator<T> {

private Function<T, String> messageProvider;
private SerializableFunction<T, String> messageProvider;

/**
* Constructs a validator with the given error message. The substring "{0}"
Expand Down
38 changes: 38 additions & 0 deletions server/src/main/java/com/vaadin/server/SerializableBiConsumer.java
@@ -0,0 +1,38 @@
/*
* 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.server;

import java.io.Serializable;
import java.util.function.BiConsumer;

/**
* A {@link BiConsumer} that is also {@link Serializable}.
*
* @see {@link BiConsumer}
* @param <T>
* the type of the first argument to the operation
* @param <U>
* the type of the second argument to the operation
*
* @since 8.0
* @author Vaadin Ltd
*
*/
@FunctionalInterface
public interface SerializableBiConsumer<T, U>
extends BiConsumer<T, U>, Serializable {
// Only method inherited from BiConsumer
}

0 comments on commit 3f37f89

Please sign in to comment.