diff options
author | Ilia Motornyi <elmot@vaadin.com> | 2017-06-29 10:30:57 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-06-29 10:30:57 +0300 |
commit | 9c3868e897541c014e19341f3d58066734f8a6c0 (patch) | |
tree | 6e0d00326c37e80d6478895e5a2470b6a203e445 | |
parent | b2c0ac2bac558a4bc497fa3a6d29b8f030511e1a (diff) | |
download | vaadin-framework-9c3868e897541c014e19341f3d58066734f8a6c0.tar.gz vaadin-framework-9c3868e897541c014e19341f3d58066734f8a6c0.zip |
Add an optional HasValue to a ValueContext
5 files changed, 85 insertions, 4 deletions
diff --git a/documentation/components/components-fields.asciidoc b/documentation/components/components-fields.asciidoc index 1415f98e73..77a308a3bb 100644 --- a/documentation/components/components-fields.asciidoc +++ b/documentation/components/components-fields.asciidoc @@ -170,7 +170,11 @@ class MyValidator implements Validator<String> { Since [interfacename]#Validator# is a functional interface, you can often simply write a lambda expression instead of a full class declaration. There is also an [methodname]#withValidator# overload that creates a -validator from a boolean function and an error message. +validator from a boolean function and an error message. If the application requires +more sophisticated validation diagnostics (e.g. locale-specific), there is a +method [methodname]#withValidator#, which uses a boolean function and an [classname]#ErrorMessageProvider#. +The [classname]#ErrorMessageProvider# can compose diagnostic messages based on the locale of the validation +and the source component value, which are provided with the [classname]#ValueContext#. [source, java] ---- diff --git a/server/src/main/java/com/vaadin/data/Binder.java b/server/src/main/java/com/vaadin/data/Binder.java index c36029aa83..26720a3274 100644 --- a/server/src/main/java/com/vaadin/data/Binder.java +++ b/server/src/main/java/com/vaadin/data/Binder.java @@ -872,9 +872,9 @@ public class Binder<BEAN> implements Serializable { */ protected ValueContext createValueContext() { if (field instanceof Component) { - return new ValueContext((Component) field); + return new ValueContext((Component) field, field); } - return new ValueContext(findLocale()); + return new ValueContext(null, field, findLocale()); } /** diff --git a/server/src/main/java/com/vaadin/data/ValueContext.java b/server/src/main/java/com/vaadin/data/ValueContext.java index 07857d34af..4ce1111ed0 100644 --- a/server/src/main/java/com/vaadin/data/ValueContext.java +++ b/server/src/main/java/com/vaadin/data/ValueContext.java @@ -33,6 +33,7 @@ import com.vaadin.ui.UI; public class ValueContext implements Serializable { private final Component component; + private final HasValue<?> hasValue; private final Locale locale; /** @@ -40,6 +41,7 @@ public class ValueContext implements Serializable { */ public ValueContext() { component = null; + hasValue = null; locale = findLocale(); } @@ -52,6 +54,7 @@ public class ValueContext implements Serializable { public ValueContext(Locale locale) { component = null; this.locale = locale; + hasValue = null; } /** @@ -59,14 +62,54 @@ public class ValueContext implements Serializable { * * @param component * The component related to current value. Can be null. + * If the component implements {@link HasValue}, it will be returned by {@link #getHasValue()} as well. */ + @SuppressWarnings("unchecked") public ValueContext(Component component) { Objects.requireNonNull(component, "Component can't be null in ValueContext construction"); this.component = component; + if(component instanceof HasValue) { + hasValue = (HasValue<?>) component; + } else { + hasValue = null; + } + locale = findLocale(); + } + + /** + * Constructor for {@code ValueContext}. + * + * @param component + * The component related to current value. Can be null. + * @param hasValue + * The value source related to current value. Can be null. + */ + public ValueContext(Component component, HasValue<?> hasValue) { + Objects.requireNonNull(component, + "Component can't be null in ValueContext construction"); + this.component = component; + this.hasValue = hasValue; locale = findLocale(); } + /** + * Constructor for {@code ValueContext}. + * + * @param + * component + * The component can be {@code null}. + * @param locale + * The locale used with conversion. Can be {@code null}. + * @param hasValue + * The value source related to current value. Can be {@code null}. + */ + public ValueContext(Component component, HasValue<?> hasValue, Locale locale) { + this.component = component; + this.hasValue = hasValue; + this.locale = locale; + } + private Locale findLocale() { Locale l = null; if (component != null) { @@ -100,4 +143,15 @@ public class ValueContext implements Serializable { public Optional<Locale> getLocale() { return Optional.ofNullable(locale); } + + /** + * Returns an {@code Optional} for the {@code HasValue} used in the value + * conversion. In certain complicated cases, ex. cross-field validation, HasValue might be not available. + * + * @return the optional of {@code HasValue} + */ + @SuppressWarnings("unused") + public Optional<HasValue<?>> getHasValue() { + return Optional.ofNullable(hasValue); + } } diff --git a/server/src/main/java/com/vaadin/ui/AbstractDateField.java b/server/src/main/java/com/vaadin/ui/AbstractDateField.java index 06e6d74c30..0e738de253 100644 --- a/server/src/main/java/com/vaadin/ui/AbstractDateField.java +++ b/server/src/main/java/com/vaadin/ui/AbstractDateField.java @@ -684,7 +684,7 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster & } else { RangeValidator<T> validator = getRangeValidator(); ValidationResult result = validator.apply(value, - new ValueContext(this)); + new ValueContext(this, this)); if (result.isError()) { setComponentError(new UserError(getDateOutOfRangeMessage())); } diff --git a/server/src/test/java/com/vaadin/data/ValueContextTest.java b/server/src/test/java/com/vaadin/data/ValueContextTest.java index 2f13a71dbb..b96f7463cb 100644 --- a/server/src/test/java/com/vaadin/data/ValueContextTest.java +++ b/server/src/test/java/com/vaadin/data/ValueContextTest.java @@ -3,6 +3,7 @@ package com.vaadin.data; import java.util.Locale; import java.util.Objects; +import com.vaadin.ui.CheckBox; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -46,6 +47,28 @@ public class ValueContextTest extends UI { Locale.getDefault(), locale); } + @Test + public void testHasValue1() { + setLocale(null); + ValueContext fromComponent = new ValueContext(textField); + Assert.assertEquals(textField, fromComponent.getHasValue().get()); + } + + @Test + public void testHasValue2() { + setLocale(null); + ValueContext fromComponent = new ValueContext(new CheckBox(), textField); + Assert.assertEquals(textField, fromComponent.getHasValue().get()); + } + + @Test + public void testHasValue3() { + setLocale(null); + ValueContext fromComponent = new ValueContext(new CheckBox(), textField, Locale.CANADA); + Assert.assertEquals(textField, fromComponent.getHasValue().get()); + Assert.assertEquals(Locale.CANADA, fromComponent.getLocale().get()); + } + @Before public void setUp() { setLocale(UI_LOCALE); |