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;
/**
@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);
}
@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);
* @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);
}
* @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) {
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.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;
* @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
/**
* 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
* 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));
}
* 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
* 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:
* 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()));
}
* 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:
* 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));
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
}
@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");
/**
* 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.
* 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
* 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) {
* 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);
}
* <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>
*
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
* 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");
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.
* @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);
*
* @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
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.
*/
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}"
--- /dev/null
+/*
+ * 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
+}
--- /dev/null
+/*
+ * 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);
+ }
+}
--- /dev/null
+/*
+ * 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;
+ }
+
+}
--- /dev/null
+/*
+ * 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
+}
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.
*
*/
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
* @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;
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;
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;
* @param predicate
* predicate used to filter data
*/
- public void setInMemoryFilter(Predicate<T> predicate) {
+ public void setInMemoryFilter(SerializablePredicate<T> predicate) {
inMemoryFilter = predicate;
reset();
}
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;
* 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.
* 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;
}
* @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;
}
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;
}
@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);
}
}
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;
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;
*/
@FunctionalInterface
public interface DescriptionGenerator<T>
- extends Function<T, String>, Serializable {
+ extends SerializableFunction<T, String> {
}
/**
// 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
*/
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;
* @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,
* 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;
* 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;
}
/**
* @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;
* @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)) {
* 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());
}
*
* @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());
}
*
* @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);
}
boolean userOriginated) {
fireEvent(new ColumnResizeEvent(this, column, userOriginated));
}
+
}
*/
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.
* 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}.
*/
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
*/
@FunctionalInterface
public interface ItemCaptionGenerator<T>
- extends Function<T, String>, Serializable {
+ extends SerializableFunction<T, String> {
/**
* Gets a caption for the {@code item}.
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;
private ItemCaptionGenerator<T> itemCaptionGenerator = String::valueOf;
- private Predicate<T> itemEnabledProvider = item -> true;
+ private SerializablePredicate<T> itemEnabledProvider = item -> true;
/**
* Constructs a new RadioButtonGroup with caption.
* @return the item enabled predicate
* @see #setItemEnabledProvider
*/
- public Predicate<T> getItemEnabledProvider() {
+ public SerializablePredicate<T> getItemEnabledProvider() {
return itemEnabledProvider;
}
* @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;
}
*/
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.
* @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}.
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.function.Predicate;
import org.junit.Assert;
import org.junit.Before;
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;
@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");
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 {
}
};
- Function<String, String> toPresentation = model -> "presentation-" + model;
+ SerializableFunction<String, String> toPresentation = model -> "presentation-"
+ + model;
Converter<String, String> converter = Converter.from(toModel,
toPresentation);
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;
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 {
/**
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
// 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) {
*
* @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<>();
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;
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
public void initialState_updateColumnCaption_defaultHeaderUpdated() {
column1.setCaption("1st");
- assertEquals("1st", grid.getDefaultHeaderRow().getCell(column1)
- .getText());
+ assertEquals("1st",
+ grid.getDefaultHeaderRow().getCell(column1).getText());
}
@Test
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());
}
grid.setDefaultHeaderRow(null);
column1.setCaption("1st");
- assertEquals("First", grid.getHeaderRow(0).getCell(column1)
- .getText());
+ assertEquals("First", grid.getHeaderRow(0).getCell(column1).getText());
}
}
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;
@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);
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;
@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
import java.util.ArrayList;
import java.util.List;
-import java.util.function.Function;
+import com.vaadin.server.SerializableFunction;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.data.DataSource;
import com.vaadin.tests.components.AbstractTestUI;
protected void setup(VaadinRequest request) {
Grid<String> grid = new Grid<>();
- grid.addColumn("Name", Function.identity());
+ grid.addColumn("Name", SerializableFunction.identity());
List<String> data = new ArrayList<>();
for (int i = 0; i < 1000; i++) {