From 855ec0f67951da7f4392ae704796340e1d1a3ff3 Mon Sep 17 00:00:00 2001 From: Teemu Suo-Anttila Date: Tue, 1 Nov 2016 11:42:15 +0200 Subject: Add error message provider to provide translations Change-Id: I657535d377c471369e8c77fa1db946c490023939 --- server/src/main/java/com/vaadin/data/Binder.java | 65 +++++++++++++++++++++- .../java/com/vaadin/data/ErrorMessageProvider.java | 42 ++++++++++++++ .../src/main/java/com/vaadin/data/Validator.java | 26 ++++++++- 3 files changed, 129 insertions(+), 4 deletions(-) create mode 100644 server/src/main/java/com/vaadin/data/ErrorMessageProvider.java (limited to 'server/src/main/java/com') diff --git a/server/src/main/java/com/vaadin/data/Binder.java b/server/src/main/java/com/vaadin/data/Binder.java index f500ef9a0a..e139bcd5c8 100644 --- a/server/src/main/java/com/vaadin/data/Binder.java +++ b/server/src/main/java/com/vaadin/data/Binder.java @@ -149,6 +149,9 @@ public class Binder implements Serializable { * property. If any validator returns a failure, the property value is * not updated. * + * @see #withValidator(SerializablePredicate, String) + * @see #withValidator(SerializablePredicate, ErrorMessageProvider) + * * @param validator * the validator to add, not null * @return this binding, for chaining @@ -167,6 +170,7 @@ public class Binder implements Serializable { * failure, the property value is not updated. * * @see #withValidator(Validator) + * @see #withValidator(SerializablePredicate, ErrorMessageProvider) * @see Validator#from(SerializablePredicate, String) * * @param predicate @@ -183,6 +187,34 @@ public class Binder implements Serializable { return withValidator(Validator.from(predicate, message)); } + /** + * A convenience method to add a validator to this binding using the + * {@link Validator#from(SerializablePredicate, ErrorMessageProvider)} + * factory method. + *

+ * Validators are applied, in registration order, when the field value + * is written to the backing property. If any validator returns a + * failure, the property value is not updated. + * + * @see #withValidator(Validator) + * @see #withValidator(SerializablePredicate, String) + * @see Validator#from(SerializablePredicate, ErrorMessageProvider) + * + * @param predicate + * the predicate performing validation, not null + * @param errorMessageProvider + * the provider to generate error messages, not null + * @return this binding, for chaining + * @throws IllegalStateException + * if {@code bind} has already been called + */ + public default Binding withValidator( + SerializablePredicate predicate, + ErrorMessageProvider errorMessageProvider) { + return withValidator( + Validator.from(predicate, errorMessageProvider)); + } + /** * Maps the binding to another data type using the given * {@link Converter}. @@ -1062,6 +1094,8 @@ public class Binder implements Serializable { * * @see #writeBean(Object) * @see #writeBeanIfValid(Object) + * @see #withValidator(SerializablePredicate, String) + * @see #withValidator(SerializablePredicate, ErrorMessageProvider) * * @param validator * the validator to add, not null @@ -1081,8 +1115,10 @@ public class Binder implements Serializable { * updated. If the validators fail, the bean instance is reverted to its * previous state. * - * @see #save(Object) - * @see #saveIfValid(Object) + * @see #writeBean(Object) + * @see #writeBeanIfValid(Object) + * @see #withValidator(Validator) + * @see #withValidator(SerializablePredicate, ErrorMessageProvider) * * @param predicate * the predicate performing validation, not null @@ -1095,6 +1131,31 @@ public class Binder implements Serializable { return withValidator(Validator.from(predicate, message)); } + /** + * A convenience method to add a validator to this binder using the + * {@link Validator#from(SerializablePredicate, ErrorMessageProvider)} + * factory method. + *

+ * Bean level validators are applied on the bean instance after the bean is + * updated. If the validators fail, the bean instance is reverted to its + * previous state. + * + * @see #writeBean(Object) + * @see #writeBeanIfValid(Object) + * @see #withValidator(Validator) + * @see #withValidator(SerializablePredicate, String) + * + * @param predicate + * the predicate performing validation, not null + * @param errorMessageProvider + * the provider to generate error messages, not null + * @return this binder, for chaining + */ + public Binder withValidator(SerializablePredicate predicate, + ErrorMessageProvider errorMessageProvider) { + return withValidator(Validator.from(predicate, errorMessageProvider)); + } + /** * Validates the values of all bound fields and returns the validation * status. diff --git a/server/src/main/java/com/vaadin/data/ErrorMessageProvider.java b/server/src/main/java/com/vaadin/data/ErrorMessageProvider.java new file mode 100644 index 0000000000..71a6723634 --- /dev/null +++ b/server/src/main/java/com/vaadin/data/ErrorMessageProvider.java @@ -0,0 +1,42 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.data; + +import com.vaadin.data.util.converter.ValueContext; +import com.vaadin.server.SerializableFunction; + +/** + * Provider interface for generating localizable error messages using + * {@link ValueContext}. + * + * @since + * @author Vaadin Ltd. + */ +@FunctionalInterface +public interface ErrorMessageProvider + extends SerializableFunction { + + /** + * Returns a generated error message for given {@code ValueContext}. + * + * @param context + * the value context + * + * @return generated error message + */ + @Override + public String apply(ValueContext context); +} diff --git a/server/src/main/java/com/vaadin/data/Validator.java b/server/src/main/java/com/vaadin/data/Validator.java index 6f1d5827ec..45a88bc7f3 100644 --- a/server/src/main/java/com/vaadin/data/Validator.java +++ b/server/src/main/java/com/vaadin/data/Validator.java @@ -101,15 +101,37 @@ public interface Validator String errorMessage) { Objects.requireNonNull(guard, "guard cannot be null"); Objects.requireNonNull(errorMessage, "errorMessage cannot be null"); + return from(guard, ctx -> errorMessage); + } + + /** + * Builds a validator out of a conditional function and an error message + * provider. If the function returns true, the validator returns + * {@code Result.ok()}; if it returns false or throws an exception, + * {@code Result.error()} is returned with the message from the provider. + * + * @param + * the value type + * @param guard + * the function used to validate, not null + * @param errorMessageProvider + * the provider to generate error messages, not null + * @return the new validator using the function + */ + public static Validator from(SerializablePredicate guard, + ErrorMessageProvider errorMessageProvider) { + Objects.requireNonNull(guard, "guard cannot be null"); + Objects.requireNonNull(errorMessageProvider, + "errorMessageProvider cannot be null"); return (value, context) -> { try { if (guard.test(value)) { return Result.ok(value); } else { - return Result.error(errorMessage); + return Result.error(errorMessageProvider.apply(context)); } } catch (Exception e) { - return Result.error(errorMessage); + return Result.error(errorMessageProvider.apply(context)); } }; } -- cgit v1.2.3