finalBinding = withConverter(createConverter(), false);
if (BeanUtil.checkBeanValidationAvailable()) {
- finalBinding = finalBinding.withValidator(new BeanValidator(
- getBinder().beanType, propertyName, findLocale()));
+ finalBinding = finalBinding.withValidator(
+ new BeanValidator(getBinder().beanType, propertyName));
}
PropertyDescriptor descriptor = getDescriptor(propertyName);
* Binds {@code property} with {@code propertyType} to the field in the
* {@code objectWithMemberFields} instance using {@code memberField} as a
* reference to a member.
- *
+ *
* @param objectWithMemberFields
* the object that contains (Java) member fields to build and
* bind
* class. If there is no suitable default constructor or you want to
* configure the instantiated class then override this method and provide
* your own implementation.
- *
+ *
* @see #bindInstanceFields(Object)
* @param fieldClass
* type of the field
private String propertyName;
private Class<?> beanType;
- private Locale locale;
/**
* Creates a new JSR-303 {@code BeanValidator} that validates values of the
* false
*/
public BeanValidator(Class<?> beanType, String propertyName) {
- this(beanType, propertyName, Locale.getDefault());
- }
-
- /**
- * Creates a new JSR-303 {@code BeanValidator} that validates values of the
- * specified property. Localizes validation messages using the given locale.
- *
- * @param beanType
- * the bean class declaring the property, not null
- * @param propertyName
- * the property to validate, not null
- * @param locale
- * the locale to use, not null
- * @throws IllegalStateException
- * if {@link BeanUtil#checkBeanValidationAvailable()} returns
- * false
- */
- public BeanValidator(Class<?> beanType, String propertyName,
- Locale locale) {
if (!BeanUtil.checkBeanValidationAvailable()) {
throw new IllegalStateException("Cannot create a "
+ BeanValidator.class.getSimpleName()
this.beanType = beanType;
this.propertyName = propertyName;
- setLocale(locale);
}
/**
* <p>
* Null values are accepted unless the property has an {@code @NotNull}
* annotation or equivalent.
+ *
+ * @param value
+ * the input value to validate
+ * @param context
+ * the value context for validation
+ * @return the validation result
*/
@Override
public Result<Object> apply(final Object value, ValueContext context) {
BinaryOperator<Result<Object>> accumulator = (result1,
result2) -> result1.flatMap(val -> result2);
+ Locale locale = context.getLocale().orElse(Locale.getDefault());
- return violations.stream().map(v -> Result.error(getMessage(v)))
+ return violations.stream().map(v -> Result.error(getMessage(v, locale)))
.reduce(Result.ok(value), accumulator);
}
- /**
- * Returns the locale used for validation error messages.
- *
- * @return the locale used for error messages
- */
- public Locale getLocale() {
- return locale;
- }
-
@Override
public String toString() {
return String.format("%s[%s.%s]", getClass().getSimpleName(),
* Returns the interpolated error message for the given constraint violation
* using the locale specified for this validator.
*
- * @param v
+ * @param violation
* the constraint violation
+ * @param locale
+ * the used locale
* @return the localized error message
*/
- protected String getMessage(ConstraintViolation<?> v) {
+ protected String getMessage(ConstraintViolation<?> violation,
+ Locale locale) {
return getJavaxBeanValidatorFactory().getMessageInterpolator()
- .interpolate(v.getMessageTemplate(), createContext(v), locale);
+ .interpolate(violation.getMessageTemplate(),
+ createContext(violation), locale);
}
/**
return new ContextImpl(violation);
}
- /**
- * Sets the locale used for validation error messages. Revalidation is not
- * automatically triggered by setting the locale.
- *
- * @param locale
- * the locale to use for error messages, not null
- */
- private void setLocale(Locale locale) {
- Objects.requireNonNull(locale, "locale cannot be null");
- this.locale = locale;
- }
-
private static class LazyFactoryInitializer implements Serializable {
private static final ValidatorFactory FACTORY = getFactory();
import com.vaadin.tests.data.bean.Address;
import com.vaadin.tests.data.bean.BeanToValidate;
+import com.vaadin.tests.util.MockUI;
+import com.vaadin.ui.UI;
public class BeanValidatorTest extends ValidatorTestBase {
@Test
public void testInvalidDecimalsFailsInFrench() {
- BeanValidator v = validator("decimals", Locale.FRENCH);
+ MockUI ui = new MockUI();
+ ui.setLocale(Locale.FRENCH);
+ UI.setCurrent(ui);
+ BeanValidator v = validator("decimals");
assertFails("1234.567", "Valeur numérique hors limite "
+ "(<3 chiffres>.<2 chiffres> attendus)", v);
}
return new BeanValidator(BeanToValidate.class, propertyName);
}
- private BeanValidator validator(String propertyName, Locale locale) {
- return new BeanValidator(BeanToValidate.class, propertyName, locale);
- }
}