diff options
Diffstat (limited to 'server')
24 files changed, 400 insertions, 135 deletions
diff --git a/server/src/main/java/com/vaadin/data/BeanBinder.java b/server/src/main/java/com/vaadin/data/BeanBinder.java index 96654e37a0..a57082357f 100644 --- a/server/src/main/java/com/vaadin/data/BeanBinder.java +++ b/server/src/main/java/com/vaadin/data/BeanBinder.java @@ -21,12 +21,13 @@ import java.beans.PropertyDescriptor; 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; /** @@ -63,7 +64,8 @@ public class BeanBinder<BEAN> extends Binder<BEAN> { @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); } @@ -74,16 +76,16 @@ public class BeanBinder<BEAN> extends Binder<BEAN> { @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); @@ -110,7 +112,7 @@ public class BeanBinder<BEAN> extends Binder<BEAN> { * @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); } @@ -294,8 +296,7 @@ public class BeanBinder<BEAN> extends Binder<BEAN> { * @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) { diff --git a/server/src/main/java/com/vaadin/data/Binder.java b/server/src/main/java/com/vaadin/data/Binder.java index 5493712cec..d3c2befefb 100644 --- a/server/src/main/java/com/vaadin/data/Binder.java +++ b/server/src/main/java/com/vaadin/data/Binder.java @@ -28,8 +28,6 @@ import java.util.Objects; 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; @@ -37,6 +35,9 @@ 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; @@ -139,8 +140,8 @@ public class Binder<BEAN> implements 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 @@ -159,14 +160,14 @@ public class Binder<BEAN> implements Serializable { /** * 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 @@ -177,7 +178,8 @@ public class Binder<BEAN> implements Serializable { * 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)); } @@ -189,8 +191,8 @@ public class Binder<BEAN> implements Serializable { * 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 @@ -215,8 +217,8 @@ public class Binder<BEAN> implements Serializable { * 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: @@ -235,8 +237,8 @@ public class Binder<BEAN> implements Serializable { * 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())); } @@ -250,8 +252,8 @@ public class Binder<BEAN> implements Serializable { * 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: @@ -273,8 +275,8 @@ public class Binder<BEAN> implements Serializable { * 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)); @@ -411,8 +413,8 @@ public class Binder<BEAN> implements Serializable { 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 @@ -443,8 +445,8 @@ public class Binder<BEAN> implements Serializable { } @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"); @@ -717,7 +719,7 @@ public class Binder<BEAN> implements Serializable { /** * 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. @@ -727,7 +729,11 @@ public class Binder<BEAN> implements Serializable { * 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 @@ -735,7 +741,7 @@ public class Binder<BEAN> implements Serializable { * 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) { @@ -803,8 +809,8 @@ public class Binder<BEAN> implements Serializable { * 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); } @@ -1151,7 +1157,8 @@ public class Binder<BEAN> implements Serializable { * <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> * diff --git a/server/src/main/java/com/vaadin/data/Validator.java b/server/src/main/java/com/vaadin/data/Validator.java index 5eda581284..4d4a19fbe8 100644 --- a/server/src/main/java/com/vaadin/data/Validator.java +++ b/server/src/main/java/com/vaadin/data/Validator.java @@ -21,6 +21,8 @@ import java.util.Objects; 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 @@ -117,7 +119,7 @@ public interface Validator<T> extends Function<T, Result<T>>, Serializable { * 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"); diff --git a/server/src/main/java/com/vaadin/data/util/converter/Converter.java b/server/src/main/java/com/vaadin/data/util/converter/Converter.java index c25c567773..3521789e5a 100644 --- a/server/src/main/java/com/vaadin/data/util/converter/Converter.java +++ b/server/src/main/java/com/vaadin/data/util/converter/Converter.java @@ -22,6 +22,7 @@ import java.util.function.Function; 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. @@ -108,9 +109,10 @@ public interface Converter<PRESENTATION, MODEL> extends Serializable { * @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); @@ -131,8 +133,9 @@ public interface Converter<PRESENTATION, MODEL> extends Serializable { * * @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 diff --git a/server/src/main/java/com/vaadin/data/validator/AbstractValidator.java b/server/src/main/java/com/vaadin/data/validator/AbstractValidator.java index ea390ae7f7..b798d2bf73 100644 --- a/server/src/main/java/com/vaadin/data/validator/AbstractValidator.java +++ b/server/src/main/java/com/vaadin/data/validator/AbstractValidator.java @@ -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. @@ -31,7 +31,7 @@ import com.vaadin.data.Validator; */ 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}" diff --git a/server/src/main/java/com/vaadin/server/SerializableBiConsumer.java b/server/src/main/java/com/vaadin/server/SerializableBiConsumer.java new file mode 100644 index 0000000000..bdf83dd9ba --- /dev/null +++ b/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 +} diff --git a/server/src/main/java/com/vaadin/server/SerializableComparator.java b/server/src/main/java/com/vaadin/server/SerializableComparator.java new file mode 100644 index 0000000000..213cc5cc49 --- /dev/null +++ b/server/src/main/java/com/vaadin/server/SerializableComparator.java @@ -0,0 +1,49 @@ +/* + * 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.Comparator; + +/** + * A {@link Comparator} that is also {@link Serializable}. + * + * @author Vaadin Ltd + * @param <T> + * the type of objects that may be compared by this comparator + * @since 8.0 + * + */ +@FunctionalInterface +public interface SerializableComparator<T> extends Comparator<T>, Serializable { + + /** + * Returns a {@link SerializableComparator} instance which delegates its + * logic to the provided {@code comparator}. + * + * @param comparator + * comparator to convert + * @param <T> + * the type of objects that may be compared by this comparator + * @param <C> + * the comparator type + * @return a SerializableComparator view of the {@code comparator} + */ + static <C extends Comparator<T> & Serializable, T> SerializableComparator<T> asInstance( + C comparator) { + return (arg1, arg2) -> comparator.compare(arg1, arg2); + } +} diff --git a/server/src/main/java/com/vaadin/server/SerializableFunction.java b/server/src/main/java/com/vaadin/server/SerializableFunction.java new file mode 100644 index 0000000000..330be5f72a --- /dev/null +++ b/server/src/main/java/com/vaadin/server/SerializableFunction.java @@ -0,0 +1,46 @@ +/* + * 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.Function; + +/** + * A {@link Function} that is also {@link Serializable}. + * + * @see Function + * @author Vaadin Ltd + * @since 8.0 + * @param <T> + * the type of the input to the function + * @param <R> + * the type of the result of the function + */ +@FunctionalInterface +public interface SerializableFunction<T, R> + extends Function<T, R>, Serializable { + /** + * Returns a function 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 + */ + static <T> SerializableFunction<T, T> identity() { + return t -> t; + } + +} diff --git a/server/src/main/java/com/vaadin/server/SerializablePredicate.java b/server/src/main/java/com/vaadin/server/SerializablePredicate.java new file mode 100644 index 0000000000..5172aebe70 --- /dev/null +++ b/server/src/main/java/com/vaadin/server/SerializablePredicate.java @@ -0,0 +1,32 @@ +/* + * 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.Predicate; + +/** + * A {@link Predicate} that is also {@link Serializable}. + * + * @author Vaadin Ltd + * @since 8.0 + * @param <T> + * the type of the input to the predicate + * + */ +public interface SerializablePredicate<T> extends Predicate<T>, Serializable { + // Only method inherited from Function +} diff --git a/server/src/main/java/com/vaadin/server/data/BackEndDataSource.java b/server/src/main/java/com/vaadin/server/data/BackEndDataSource.java index c792ebd23e..2eedeb6839 100644 --- a/server/src/main/java/com/vaadin/server/data/BackEndDataSource.java +++ b/server/src/main/java/com/vaadin/server/data/BackEndDataSource.java @@ -18,9 +18,10 @@ package com.vaadin.server.data; import java.util.ArrayList; import java.util.List; import java.util.Objects; -import java.util.function.Function; import java.util.stream.Stream; +import com.vaadin.server.SerializableFunction; + /** * A {@link DataSource} for any back end. * @@ -29,8 +30,8 @@ import java.util.stream.Stream; */ public class BackEndDataSource<T> extends AbstractDataSource<T> { - private Function<Query, Stream<T>> request; - private Function<Query, Integer> sizeCallback; + private SerializableFunction<Query, Stream<T>> request; + private SerializableFunction<Query, Integer> sizeCallback; /** * Constructs a new DataSource to request data from an arbitrary back end @@ -41,8 +42,8 @@ public class BackEndDataSource<T> extends AbstractDataSource<T> { * @param sizeCallback * function that return the amount of data in back end for query */ - public BackEndDataSource(Function<Query, Stream<T>> request, - Function<Query, Integer> sizeCallback) { + public BackEndDataSource(SerializableFunction<Query, Stream<T>> request, + SerializableFunction<Query, Integer> sizeCallback) { Objects.requireNonNull(request, "Request function can't be null"); Objects.requireNonNull(sizeCallback, "Size callback can't be null"); this.request = request; diff --git a/server/src/main/java/com/vaadin/server/data/DataCommunicator.java b/server/src/main/java/com/vaadin/server/data/DataCommunicator.java index 8238777c64..a0ce859892 100644 --- a/server/src/main/java/com/vaadin/server/data/DataCommunicator.java +++ b/server/src/main/java/com/vaadin/server/data/DataCommunicator.java @@ -31,6 +31,7 @@ import java.util.stream.Stream; import com.vaadin.server.AbstractExtension; import com.vaadin.server.KeyMapper; +import com.vaadin.server.SerializablePredicate; import com.vaadin.shared.Range; import com.vaadin.shared.Registration; import com.vaadin.shared.data.DataCommunicatorClientRpc; @@ -187,7 +188,7 @@ public class DataCommunicator<T> extends AbstractExtension { private Range pushRows = Range.withLength(0, 40); private Comparator<T> inMemorySorting; - private Predicate<T> inMemoryFilter; + private SerializablePredicate<T> inMemoryFilter; private List<SortOrder<String>> backEndSorting = new ArrayList<>(); private DataCommunicatorClientRpc rpc; @@ -406,7 +407,7 @@ public class DataCommunicator<T> extends AbstractExtension { * @param predicate * predicate used to filter data */ - public void setInMemoryFilter(Predicate<T> predicate) { + public void setInMemoryFilter(SerializablePredicate<T> predicate) { inMemoryFilter = predicate; reset(); } diff --git a/server/src/main/java/com/vaadin/ui/AbstractMultiSelect.java b/server/src/main/java/com/vaadin/ui/AbstractMultiSelect.java index 7332941f91..0ac647e3af 100644 --- a/server/src/main/java/com/vaadin/ui/AbstractMultiSelect.java +++ b/server/src/main/java/com/vaadin/ui/AbstractMultiSelect.java @@ -30,6 +30,7 @@ import com.vaadin.event.selection.MultiSelectionEvent; import com.vaadin.event.selection.MultiSelectionListener; import com.vaadin.server.Resource; import com.vaadin.server.ResourceReference; +import com.vaadin.server.SerializablePredicate; import com.vaadin.server.data.DataGenerator; import com.vaadin.shared.Registration; import com.vaadin.shared.data.selection.MultiSelectServerRpc; @@ -279,7 +280,7 @@ public abstract class AbstractMultiSelect<T> * The item enabled status provider. It is up to the implementing class to * support this or not. */ - private Predicate<T> itemEnabledProvider = item -> true; + private SerializablePredicate<T> itemEnabledProvider = item -> true; /** * Creates a new multi select with an empty data source. @@ -440,14 +441,14 @@ public abstract class AbstractMultiSelect<T> * Returns the item enabled provider for this multiselect. * <p> * <em>Implementation note:</em> Override this method and - * {@link #setItemEnabledProvider(Predicate)} as {@code public} and invoke - * {@code super} methods to support this feature in the multiselect - * component. + * {@link #setItemEnabledProvider(SerializablePredicate)} as {@code public} + * and invoke {@code super} methods to support this feature in the + * multiselect component. * * @return the item enabled provider, not {@code null} * @see #setItemEnabledProvider(Predicate) */ - protected Predicate<T> getItemEnabledProvider() { + protected SerializablePredicate<T> getItemEnabledProvider() { return itemEnabledProvider; } @@ -466,7 +467,8 @@ public abstract class AbstractMultiSelect<T> * @param itemEnabledProvider * the item enabled provider to set, not {@code null} */ - protected void setItemEnabledProvider(Predicate<T> itemEnabledProvider) { + protected void setItemEnabledProvider( + SerializablePredicate<T> itemEnabledProvider) { Objects.requireNonNull(itemEnabledProvider); this.itemEnabledProvider = itemEnabledProvider; } diff --git a/server/src/main/java/com/vaadin/ui/CheckBoxGroup.java b/server/src/main/java/com/vaadin/ui/CheckBoxGroup.java index 0a1e4c71af..c088949899 100644 --- a/server/src/main/java/com/vaadin/ui/CheckBoxGroup.java +++ b/server/src/main/java/com/vaadin/ui/CheckBoxGroup.java @@ -17,9 +17,9 @@ package com.vaadin.ui; import java.util.Collection; -import java.util.function.Predicate; import com.vaadin.data.Listing; +import com.vaadin.server.SerializablePredicate; import com.vaadin.server.data.DataSource; import com.vaadin.shared.ui.optiongroup.CheckBoxGroupState; @@ -128,12 +128,13 @@ public class CheckBoxGroup<T> extends AbstractMultiSelect<T> { } @Override - public Predicate<T> getItemEnabledProvider() { + public SerializablePredicate<T> getItemEnabledProvider() { return super.getItemEnabledProvider(); } @Override - public void setItemEnabledProvider(Predicate<T> itemEnabledProvider) { + public void setItemEnabledProvider( + SerializablePredicate<T> itemEnabledProvider) { super.setItemEnabledProvider(itemEnabledProvider); } } diff --git a/server/src/main/java/com/vaadin/ui/Grid.java b/server/src/main/java/com/vaadin/ui/Grid.java index b904565a64..db85ec1fb2 100644 --- a/server/src/main/java/com/vaadin/ui/Grid.java +++ b/server/src/main/java/com/vaadin/ui/Grid.java @@ -32,6 +32,7 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.function.BinaryOperator; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -41,6 +42,8 @@ import com.vaadin.event.ContextClickEvent; import com.vaadin.event.EventListener; import com.vaadin.server.EncodeResult; import com.vaadin.server.JsonCodec; +import com.vaadin.server.SerializableComparator; +import com.vaadin.server.SerializableFunction; import com.vaadin.server.data.SortOrder; import com.vaadin.shared.MouseEventDetails; import com.vaadin.shared.Registration; @@ -461,7 +464,7 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents { */ @FunctionalInterface public interface DescriptionGenerator<T> - extends Function<T, String>, Serializable { + extends SerializableFunction<T, String> { } /** @@ -539,10 +542,14 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents { // Set sort orders // In-memory comparator - Comparator<T> comparator = sortOrder.stream() + BinaryOperator<SerializableComparator<T>> operator = (comparator1, + comparator2) -> SerializableComparator.asInstance( + (Comparator<T> & Serializable) comparator1 + .thenComparing(comparator2)); + SerializableComparator<T> comparator = sortOrder.stream() .map(order -> order.getSorted() .getComparator(order.getDirection())) - .reduce((x, y) -> 0, Comparator::thenComparing); + .reduce((x, y) -> 0, operator); getDataCommunicator().setInMemorySorting(comparator); // Back-end sort properties @@ -755,10 +762,10 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents { */ public static class Column<T, V> extends AbstractGridExtension<T> { - private final Function<T, ? extends V> valueProvider; + private final SerializableFunction<T, ? extends V> valueProvider; - private Function<SortDirection, Stream<SortOrder<String>>> sortOrderProvider; - private Comparator<T> comparator; + private SerializableFunction<SortDirection, Stream<SortOrder<String>>> sortOrderProvider; + private SerializableComparator<T> comparator; private StyleGenerator<T> styleGenerator = item -> null; private DescriptionGenerator<T> descriptionGenerator; @@ -773,7 +780,8 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents { * @param renderer * the type of value */ - protected Column(String caption, Function<T, ? extends V> valueProvider, + protected Column(String caption, + SerializableFunction<T, ? extends V> valueProvider, Renderer<V> renderer) { Objects.requireNonNull(caption, "Header caption can't be null"); Objects.requireNonNull(valueProvider, @@ -995,7 +1003,8 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents { * the comparator to use when sorting data in this column * @return this column */ - public Column<T, V> setComparator(Comparator<T> comparator) { + public Column<T, V> setComparator( + SerializableComparator<T> comparator) { Objects.requireNonNull(comparator, "Comparator can't be null"); this.comparator = comparator; return this; @@ -1009,11 +1018,13 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents { * the direction this column is sorted by * @return comparator for this column */ - public Comparator<T> getComparator(SortDirection sortDirection) { + public SerializableComparator<T> getComparator( + SortDirection sortDirection) { Objects.requireNonNull(comparator, "No comparator defined for sorted column."); boolean reverse = sortDirection != SortDirection.ASCENDING; - return reverse ? comparator.reversed() : comparator; + return reverse ? (t1, t2) -> comparator.reversed().compare(t1, t2) + : comparator; } /** @@ -1044,7 +1055,7 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents { * @return this column */ public Column<T, V> setSortOrderProvider( - Function<SortDirection, Stream<SortOrder<String>>> provider) { + SerializableFunction<SortDirection, Stream<SortOrder<String>>> provider) { Objects.requireNonNull(provider, "Sort order provider can't be null"); sortOrderProvider = provider; @@ -1708,7 +1719,7 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents { * @see {@link AbstractRenderer} */ public <V> Column<T, V> addColumn(String identifier, - Function<T, ? extends V> valueProvider, + SerializableFunction<T, ? extends V> valueProvider, AbstractRenderer<? super T, V> renderer) throws IllegalArgumentException { if (columnKeys.containsKey(identifier)) { @@ -1737,7 +1748,7 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents { * if the same identifier is used for multiple columns */ public Column<T, String> addColumn(String identifier, - Function<T, String> valueProvider) { + SerializableFunction<T, String> valueProvider) { return addColumn(identifier, valueProvider, new TextRenderer()); } @@ -1751,7 +1762,8 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents { * * @return the new column */ - public Column<T, String> addColumn(Function<T, String> valueProvider) { + public Column<T, String> addColumn( + SerializableFunction<T, String> valueProvider) { return addColumn(getGeneratedIdentifier(), valueProvider, new TextRenderer()); } @@ -1771,7 +1783,8 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents { * * @see {@link AbstractRenderer} */ - public <V> Column<T, V> addColumn(Function<T, ? extends V> valueProvider, + public <V> Column<T, V> addColumn( + SerializableFunction<T, ? extends V> valueProvider, AbstractRenderer<? super T, V> renderer) { return addColumn(getGeneratedIdentifier(), valueProvider, renderer); } @@ -2522,4 +2535,5 @@ public class Grid<T> extends AbstractSingleSelect<T> implements HasComponents { boolean userOriginated) { fireEvent(new ColumnResizeEvent(this, column, userOriginated)); } + } diff --git a/server/src/main/java/com/vaadin/ui/IconGenerator.java b/server/src/main/java/com/vaadin/ui/IconGenerator.java index 41f11dad81..50da1c5303 100644 --- a/server/src/main/java/com/vaadin/ui/IconGenerator.java +++ b/server/src/main/java/com/vaadin/ui/IconGenerator.java @@ -15,10 +15,8 @@ */ package com.vaadin.ui; -import java.io.Serializable; -import java.util.function.Function; - import com.vaadin.server.Resource; +import com.vaadin.server.SerializableFunction; /** * A callback interface for generating icons for an item. @@ -27,7 +25,7 @@ import com.vaadin.server.Resource; * item type for which the icon is generated */ @FunctionalInterface -public interface IconGenerator<T> extends Function<T, Resource>, Serializable { +public interface IconGenerator<T> extends SerializableFunction<T, Resource> { /** * Gets an icon resource for the {@code item}. diff --git a/server/src/main/java/com/vaadin/ui/ItemCaptionGenerator.java b/server/src/main/java/com/vaadin/ui/ItemCaptionGenerator.java index dc699c077b..0a57d901e9 100644 --- a/server/src/main/java/com/vaadin/ui/ItemCaptionGenerator.java +++ b/server/src/main/java/com/vaadin/ui/ItemCaptionGenerator.java @@ -15,8 +15,7 @@ */ package com.vaadin.ui; -import java.io.Serializable; -import java.util.function.Function; +import com.vaadin.server.SerializableFunction; /** * {@link ItemCaptionGenerator} can be used to customize the string shown to the @@ -30,7 +29,7 @@ import java.util.function.Function; */ @FunctionalInterface public interface ItemCaptionGenerator<T> - extends Function<T, String>, Serializable { + extends SerializableFunction<T, String> { /** * Gets a caption for the {@code item}. diff --git a/server/src/main/java/com/vaadin/ui/RadioButtonGroup.java b/server/src/main/java/com/vaadin/ui/RadioButtonGroup.java index 13aa840462..a1474c91d4 100644 --- a/server/src/main/java/com/vaadin/ui/RadioButtonGroup.java +++ b/server/src/main/java/com/vaadin/ui/RadioButtonGroup.java @@ -18,11 +18,11 @@ package com.vaadin.ui; import java.util.Collection; import java.util.Objects; -import java.util.function.Predicate; import com.vaadin.data.Listing; import com.vaadin.server.Resource; import com.vaadin.server.ResourceReference; +import com.vaadin.server.SerializablePredicate; import com.vaadin.server.data.DataGenerator; import com.vaadin.server.data.DataSource; import com.vaadin.shared.ui.ListingJsonConstants; @@ -45,7 +45,7 @@ public class RadioButtonGroup<T> extends AbstractSingleSelect<T> { private ItemCaptionGenerator<T> itemCaptionGenerator = String::valueOf; - private Predicate<T> itemEnabledProvider = item -> true; + private SerializablePredicate<T> itemEnabledProvider = item -> true; /** * Constructs a new RadioButtonGroup with caption. @@ -226,7 +226,7 @@ public class RadioButtonGroup<T> extends AbstractSingleSelect<T> { * @return the item enabled predicate * @see #setItemEnabledProvider */ - public Predicate<T> getItemEnabledProvider() { + public SerializablePredicate<T> getItemEnabledProvider() { return itemEnabledProvider; } @@ -240,7 +240,8 @@ public class RadioButtonGroup<T> extends AbstractSingleSelect<T> { * @param itemEnabledProvider * the item enable predicate, not null */ - public void setItemEnabledProvider(Predicate<T> itemEnabledProvider) { + public void setItemEnabledProvider( + SerializablePredicate<T> itemEnabledProvider) { Objects.requireNonNull(itemEnabledProvider); this.itemEnabledProvider = itemEnabledProvider; } diff --git a/server/src/main/java/com/vaadin/ui/StyleGenerator.java b/server/src/main/java/com/vaadin/ui/StyleGenerator.java index ddec2a2071..496d8a118a 100644 --- a/server/src/main/java/com/vaadin/ui/StyleGenerator.java +++ b/server/src/main/java/com/vaadin/ui/StyleGenerator.java @@ -15,8 +15,7 @@ */ package com.vaadin.ui; -import java.io.Serializable; -import java.util.function.Function; +import com.vaadin.server.SerializableFunction; /** * A callback interface for generating custom CSS class names for items. @@ -28,7 +27,7 @@ import java.util.function.Function; * @author Vaadin Ltd */ @FunctionalInterface -public interface StyleGenerator<T> extends Function<T, String>, Serializable { +public interface StyleGenerator<T> extends SerializableFunction<T, String> { /** * Gets a class name for the {@code item}. diff --git a/server/src/test/java/com/vaadin/data/BinderConverterValidatorTest.java b/server/src/test/java/com/vaadin/data/BinderConverterValidatorTest.java index 73443155c7..1ce373bf47 100644 --- a/server/src/test/java/com/vaadin/data/BinderConverterValidatorTest.java +++ b/server/src/test/java/com/vaadin/data/BinderConverterValidatorTest.java @@ -23,7 +23,6 @@ import static org.junit.Assert.assertTrue; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Predicate; import org.junit.Assert; import org.junit.Before; @@ -34,6 +33,7 @@ import com.vaadin.data.util.converter.StringToIntegerConverter; import com.vaadin.data.validator.NotEmptyValidator; import com.vaadin.server.AbstractErrorMessage; import com.vaadin.server.ErrorMessage; +import com.vaadin.server.SerializablePredicate; import com.vaadin.server.UserError; import com.vaadin.tests.data.bean.Person; import com.vaadin.ui.Label; @@ -640,7 +640,8 @@ public class BinderConverterValidatorTest @Test public void binderLoad_withCrossFieldValidation_clearsErrors() { TextField lastNameField = new TextField(); - final Predicate<String> lengthPredicate = v -> v.length() > 2; + final SerializablePredicate<String> lengthPredicate = v -> v + .length() > 2; Binding<Person, String, String> firstNameBinding = binder .forField(nameField).withValidator(lengthPredicate, "length"); diff --git a/server/src/test/java/com/vaadin/tests/data/converter/ConverterTest.java b/server/src/test/java/com/vaadin/tests/data/converter/ConverterTest.java index 95f200bdf6..6d653bb932 100644 --- a/server/src/test/java/com/vaadin/tests/data/converter/ConverterTest.java +++ b/server/src/test/java/com/vaadin/tests/data/converter/ConverterTest.java @@ -1,17 +1,16 @@ package com.vaadin.tests.data.converter; -import java.util.function.Function; - import org.junit.Assert; import org.junit.Test; import com.vaadin.data.Result; import com.vaadin.data.util.converter.Converter; import com.vaadin.data.util.converter.ValueContext; +import com.vaadin.server.SerializableFunction; public class ConverterTest { - Function<String, Result<String>> toModel = presentation -> { + SerializableFunction<String, Result<String>> toModel = presentation -> { if (presentation.startsWith("presentation-")) { return Result.ok(presentation.substring("presentation-".length())); } else { @@ -19,7 +18,8 @@ public class ConverterTest { } }; - Function<String, String> toPresentation = model -> "presentation-" + model; + SerializableFunction<String, String> toPresentation = model -> "presentation-" + + model; Converter<String, String> converter = Converter.from(toModel, toPresentation); diff --git a/server/src/test/java/com/vaadin/tests/server/ClassesSerializableTest.java b/server/src/test/java/com/vaadin/tests/server/ClassesSerializableTest.java index ea002f37f6..0a1629c2f9 100644 --- a/server/src/test/java/com/vaadin/tests/server/ClassesSerializableTest.java +++ b/server/src/test/java/com/vaadin/tests/server/ClassesSerializableTest.java @@ -1,9 +1,18 @@ package com.vaadin.tests.server; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.io.Serializable; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -11,12 +20,17 @@ import java.util.Comparator; import java.util.Enumeration; import java.util.Iterator; import java.util.List; +import java.util.Optional; import java.util.jar.JarEntry; import java.util.jar.JarFile; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.junit.Assert; import org.junit.Test; +import com.vaadin.ui.Component; + public class ClassesSerializableTest { /** @@ -99,16 +113,30 @@ public class ClassesSerializableTest { classes.addAll(findServerClasses(location)); } + ArrayList<Field> nonSerializableFunctionFields = new ArrayList<>(); + ArrayList<Class<?>> nonSerializableClasses = new ArrayList<>(); for (String className : classes) { Class<?> cls = Class.forName(className); + // Don't add classes that have a @Ignore annotation on the class + if (isTestClass(cls)) { + continue; + } + + // report fields that use lambda types that won't be serializable + // (also in syntehtic classes) + Stream.of(cls.getDeclaredFields()) + .filter(field -> isFunctionalType(field.getGenericType())) + .forEach(nonSerializableFunctionFields::add); + // skip annotations and synthetic classes if (cls.isAnnotation() || cls.isSynthetic()) { continue; } - // Don't add classes that have a @Ignore annotation on the class - if (isTestClass(cls)) { - continue; + + if (Component.class.isAssignableFrom(cls) && !cls.isInterface() + && !Modifier.isAbstract(cls.getModifiers())) { + serializeAndDeserialize(cls); } // report non-serializable classes and interfaces @@ -135,26 +163,71 @@ public class ClassesSerializableTest { // useful failure message including all non-serializable classes and // interfaces if (!nonSerializableClasses.isEmpty()) { - String nonSerializableString = ""; - Iterator<Class<?>> it = nonSerializableClasses.iterator(); - while (it.hasNext()) { - Class c = it.next(); - nonSerializableString += ", " + c.getName(); - if (c.isAnonymousClass()) { - nonSerializableString += "(super: "; - nonSerializableString += c.getSuperclass().getName(); - nonSerializableString += ", interfaces: "; - for (Class i : c.getInterfaces()) { - nonSerializableString += i.getName(); - nonSerializableString += ","; - } - nonSerializableString += ")"; + failSerializableClasses(nonSerializableClasses); + } + + if (!nonSerializableFunctionFields.isEmpty()) { + failSerializableFields(nonSerializableFunctionFields); + } + } + + private void serializeAndDeserialize(Class<?> clazz) + throws IOException, ClassNotFoundException, InstantiationException, + IllegalAccessException, IllegalArgumentException, + InvocationTargetException { + Optional<Constructor<?>> defaultCtor = Stream + .of(clazz.getDeclaredConstructors()) + .filter(ctor -> ctor.getParameterCount() == 0).findFirst(); + if (!defaultCtor.isPresent()) { + return; + } + defaultCtor.get().setAccessible(true); + Object instance = defaultCtor.get().newInstance(); + ByteArrayOutputStream bs = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(bs); + out.writeObject(instance); + byte[] data = bs.toByteArray(); + ObjectInputStream in = new ObjectInputStream( + new ByteArrayInputStream(data)); + in.readObject(); + } + + private void failSerializableFields( + ArrayList<Field> nonSerializableFunctionFields) { + String nonSerializableString = nonSerializableFunctionFields.stream() + .map(field -> String.format("%s.%s", + field.getDeclaringClass().getName(), field.getName())) + .collect(Collectors.joining(", ")); + + Assert.fail("Fields with functional types that are not serializable: " + + nonSerializableString); + } + + private void failSerializableClasses( + ArrayList<Class<?>> nonSerializableClasses) { + String nonSerializableString = ""; + Iterator<Class<?>> it = nonSerializableClasses.iterator(); + while (it.hasNext()) { + Class<?> c = it.next(); + nonSerializableString += ", " + c.getName(); + if (c.isAnonymousClass()) { + nonSerializableString += "(super: "; + nonSerializableString += c.getSuperclass().getName(); + nonSerializableString += ", interfaces: "; + for (Class<?> i : c.getInterfaces()) { + nonSerializableString += i.getName(); + nonSerializableString += ","; } + nonSerializableString += ")"; } - Assert.fail( - "Serializable not implemented by the following classes and interfaces: " - + nonSerializableString); } + Assert.fail( + "Serializable not implemented by the following classes and interfaces: " + + nonSerializableString); + } + + private static boolean isFunctionalType(Type type) { + return type.getTypeName().contains("java.util.function"); } private boolean isTestClass(Class<?> cls) { @@ -181,7 +254,6 @@ public class ClassesSerializableTest { * * @return List of class path segment strings */ - // private final static List<String> getRawClasspathEntries() { // try to keep the order of the classpath List<String> locations = new ArrayList<>(); diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/GridDefaultHeaderTest.java b/server/src/test/java/com/vaadin/tests/server/component/grid/GridDefaultHeaderTest.java index 80984cc647..0d677a8f04 100644 --- a/server/src/test/java/com/vaadin/tests/server/component/grid/GridDefaultHeaderTest.java +++ b/server/src/test/java/com/vaadin/tests/server/component/grid/GridDefaultHeaderTest.java @@ -19,11 +19,10 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; -import java.util.function.Function; - import org.junit.Before; import org.junit.Test; +import com.vaadin.server.SerializableFunction; import com.vaadin.ui.Grid; import com.vaadin.ui.Grid.Column; import com.vaadin.ui.Grid.HeaderRow; @@ -36,8 +35,8 @@ public class GridDefaultHeaderTest { public void setUp() { grid = new Grid<>(); - column1 = grid.addColumn("First", Function.identity()); - column2 = grid.addColumn("Second", Function.identity()); + column1 = grid.addColumn("First", SerializableFunction.identity()); + column2 = grid.addColumn("Second", SerializableFunction.identity()); } @Test @@ -62,8 +61,8 @@ public class GridDefaultHeaderTest { public void initialState_updateColumnCaption_defaultHeaderUpdated() { column1.setCaption("1st"); - assertEquals("1st", grid.getDefaultHeaderRow().getCell(column1) - .getText()); + assertEquals("1st", + grid.getDefaultHeaderRow().getCell(column1).getText()); } @Test @@ -71,8 +70,8 @@ public class GridDefaultHeaderTest { grid.setDefaultHeaderRow(grid.appendHeaderRow()); column1.setCaption("1st"); - assertEquals("1st", grid.getDefaultHeaderRow().getCell(column1) - .getText()); + assertEquals("1st", + grid.getDefaultHeaderRow().getCell(column1).getText()); assertEquals("First", grid.getHeaderRow(0).getCell(column1).getText()); } @@ -81,7 +80,6 @@ public class GridDefaultHeaderTest { grid.setDefaultHeaderRow(null); column1.setCaption("1st"); - assertEquals("First", grid.getHeaderRow(0).getCell(column1) - .getText()); + assertEquals("First", grid.getHeaderRow(0).getCell(column1).getText()); } } diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/GridHeaderFooterTest.java b/server/src/test/java/com/vaadin/tests/server/component/grid/GridHeaderFooterTest.java index a566ae3685..1309297e36 100644 --- a/server/src/test/java/com/vaadin/tests/server/component/grid/GridHeaderFooterTest.java +++ b/server/src/test/java/com/vaadin/tests/server/component/grid/GridHeaderFooterTest.java @@ -20,11 +20,10 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.fail; -import java.util.function.Function; - import org.junit.Before; import org.junit.Test; +import com.vaadin.server.SerializableFunction; import com.vaadin.ui.Grid; import com.vaadin.ui.Grid.Column; import com.vaadin.ui.Grid.HeaderRow; @@ -140,14 +139,16 @@ public class GridHeaderFooterTest { @Test public void addColumn_headerCellAdded() { - Column<?, ?> column = grid.addColumn("Col", Function.identity()); + Column<?, ?> column = grid.addColumn("Col", + SerializableFunction.identity()); assertNotNull(grid.getHeaderRow(0).getCell(column)); } @Test(expected = IllegalArgumentException.class) public void removeColumn_headerCellRemoved() { - Column<String, ?> column = grid.addColumn("Col", Function.identity()); + Column<String, ?> column = grid.addColumn("Col", + SerializableFunction.identity()); grid.removeColumn(column); grid.getHeaderRow(0).getCell(column); diff --git a/server/src/test/java/com/vaadin/tests/server/component/grid/GridTest.java b/server/src/test/java/com/vaadin/tests/server/component/grid/GridTest.java index eec20e2b9d..942228ed34 100644 --- a/server/src/test/java/com/vaadin/tests/server/component/grid/GridTest.java +++ b/server/src/test/java/com/vaadin/tests/server/component/grid/GridTest.java @@ -2,11 +2,10 @@ package com.vaadin.tests.server.component.grid; import static org.junit.Assert.assertEquals; -import java.util.function.Function; - import org.junit.Before; import org.junit.Test; +import com.vaadin.server.SerializableFunction; import com.vaadin.shared.ui.grid.HeightMode; import com.vaadin.ui.Grid; import com.vaadin.ui.renderers.NumberRenderer; @@ -18,9 +17,9 @@ public class GridTest { @Before public void setUp() { grid = new Grid<>(); - grid.addColumn("foo", Function.identity()); + grid.addColumn("foo", SerializableFunction.identity()); grid.addColumn(String::length, new NumberRenderer()); - grid.addColumn("randomColumnId", Function.identity()); + grid.addColumn("randomColumnId", SerializableFunction.identity()); } @Test |