summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorTeemu Suo-Anttila <tsuoanttila@users.noreply.github.com>2018-03-19 19:04:48 +0200
committerIlia Motornyi <elmot@vaadin.com>2018-03-19 19:04:48 +0200
commit0a3e1640c69b2a0e9ae772eca08c1dd990aafb7c (patch)
treec768c6a402ed7422c9dfa401c08b1516a28ead7d /server
parent5aa6433972b2b0980bcb9a658f28a72e426453f8 (diff)
downloadvaadin-framework-0a3e1640c69b2a0e9ae772eca08c1dd990aafb7c.tar.gz
vaadin-framework-0a3e1640c69b2a0e9ae772eca08c1dd990aafb7c.zip
Add option to use error message provider for StringTo converters (#10711)
Diffstat (limited to 'server')
-rw-r--r--server/src/main/java/com/vaadin/data/converter/AbstractStringToNumberConverter.java40
-rw-r--r--server/src/main/java/com/vaadin/data/converter/StringToBigDecimalConverter.java34
-rw-r--r--server/src/main/java/com/vaadin/data/converter/StringToBigIntegerConverter.java53
-rw-r--r--server/src/main/java/com/vaadin/data/converter/StringToBooleanConverter.java41
-rw-r--r--server/src/main/java/com/vaadin/data/converter/StringToDoubleConverter.java34
-rw-r--r--server/src/main/java/com/vaadin/data/converter/StringToFloatConverter.java34
-rw-r--r--server/src/main/java/com/vaadin/data/converter/StringToIntegerConverter.java36
-rw-r--r--server/src/main/java/com/vaadin/data/converter/StringToLongConverter.java34
-rw-r--r--server/src/test/java/com/vaadin/data/BinderTest.java23
9 files changed, 294 insertions, 35 deletions
diff --git a/server/src/main/java/com/vaadin/data/converter/AbstractStringToNumberConverter.java b/server/src/main/java/com/vaadin/data/converter/AbstractStringToNumberConverter.java
index b3aff7c0e7..3918dc5447 100644
--- a/server/src/main/java/com/vaadin/data/converter/AbstractStringToNumberConverter.java
+++ b/server/src/main/java/com/vaadin/data/converter/AbstractStringToNumberConverter.java
@@ -21,6 +21,7 @@ import java.text.ParsePosition;
import java.util.Locale;
import com.vaadin.data.Converter;
+import com.vaadin.data.ErrorMessageProvider;
import com.vaadin.data.Result;
import com.vaadin.data.ValueContext;
@@ -39,11 +40,29 @@ import com.vaadin.data.ValueContext;
public abstract class AbstractStringToNumberConverter<T extends Number>
implements Converter<String, T> {
- private final String errorMessage;
+ private final ErrorMessageProvider errorMessageProvider;
private T emptyValue;
/**
* Creates a new converter instance with the given empty string value and
+ * error message provider.
+ *
+ * @param emptyValue
+ * the presentation value to return when converting an empty
+ * string, may be <code>null</code>
+ * @param errorMessageProvider
+ * the error message provider to use if conversion fails
+ *
+ * @since
+ */
+ protected AbstractStringToNumberConverter(T emptyValue,
+ ErrorMessageProvider errorMessageProvider) {
+ this.emptyValue = emptyValue;
+ this.errorMessageProvider = errorMessageProvider;
+ }
+
+ /**
+ * Creates a new converter instance with the given empty string value and
* error message.
*
* @param emptyValue
@@ -54,8 +73,7 @@ public abstract class AbstractStringToNumberConverter<T extends Number>
*/
protected AbstractStringToNumberConverter(T emptyValue,
String errorMessage) {
- this.emptyValue = emptyValue;
- this.errorMessage = errorMessage;
+ this(emptyValue, ctx -> errorMessage);
}
/**
@@ -81,11 +99,12 @@ public abstract class AbstractStringToNumberConverter<T extends Number>
*
* @param value
* The value to convert
- * @param locale
- * The locale to use for conversion
+ * @param context
+ * The value context for conversion
* @return The converted value
*/
- protected Result<Number> convertToNumber(String value, Locale locale) {
+ protected Result<Number> convertToNumber(String value,
+ ValueContext context) {
if (value == null) {
return Result.ok(null);
}
@@ -96,9 +115,10 @@ public abstract class AbstractStringToNumberConverter<T extends Number>
// Parse and detect errors. If the full string was not used, it is
// an error.
ParsePosition parsePosition = new ParsePosition(0);
- Number parsedValue = getFormat(locale).parse(value, parsePosition);
+ Number parsedValue = getFormat(context.getLocale().orElse(null))
+ .parse(value, parsePosition);
if (parsePosition.getIndex() != value.length()) {
- return Result.error(getErrorMessage());
+ return Result.error(getErrorMessage(context));
}
if (parsedValue == null) {
@@ -114,8 +134,8 @@ public abstract class AbstractStringToNumberConverter<T extends Number>
*
* @return the error message
*/
- protected String getErrorMessage() {
- return errorMessage;
+ protected String getErrorMessage(ValueContext context) {
+ return errorMessageProvider.apply(context);
}
@Override
diff --git a/server/src/main/java/com/vaadin/data/converter/StringToBigDecimalConverter.java b/server/src/main/java/com/vaadin/data/converter/StringToBigDecimalConverter.java
index 9418e53e1f..c3a55561bf 100644
--- a/server/src/main/java/com/vaadin/data/converter/StringToBigDecimalConverter.java
+++ b/server/src/main/java/com/vaadin/data/converter/StringToBigDecimalConverter.java
@@ -20,6 +20,7 @@ import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
+import com.vaadin.data.ErrorMessageProvider;
import com.vaadin.data.Result;
import com.vaadin.data.ValueContext;
@@ -66,6 +67,37 @@ public class StringToBigDecimalConverter
super(emptyValue, errorMessage);
}
+ /**
+ * Creates a new converter instance with the given error message provider.
+ * Empty strings are converted to <code>null</code>.
+ *
+ * @param errorMessageProvider
+ * the error message provider to use if conversion fails
+ *
+ * @since
+ */
+ public StringToBigDecimalConverter(
+ ErrorMessageProvider errorMessageProvider) {
+ this(null, errorMessageProvider);
+ }
+
+ /**
+ * Creates a new converter instance with the given empty string value and
+ * error message provider.
+ *
+ * @param emptyValue
+ * the presentation value to return when converting an empty
+ * string, may be <code>null</code>
+ * @param errorMessageProvider
+ * the error message provider to use if conversion fails
+ *
+ * @since
+ */
+ public StringToBigDecimalConverter(BigDecimal emptyValue,
+ ErrorMessageProvider errorMessageProvider) {
+ super(emptyValue, errorMessageProvider);
+ }
+
@Override
protected NumberFormat getFormat(Locale locale) {
NumberFormat numberFormat = super.getFormat(locale);
@@ -79,7 +111,7 @@ public class StringToBigDecimalConverter
@Override
public Result<BigDecimal> convertToModel(String value,
ValueContext context) {
- return convertToNumber(value, context.getLocale().orElse(null))
+ return convertToNumber(value, context)
.map(number -> (BigDecimal) number);
}
diff --git a/server/src/main/java/com/vaadin/data/converter/StringToBigIntegerConverter.java b/server/src/main/java/com/vaadin/data/converter/StringToBigIntegerConverter.java
index 840f6ae8c0..0d3642cb94 100644
--- a/server/src/main/java/com/vaadin/data/converter/StringToBigIntegerConverter.java
+++ b/server/src/main/java/com/vaadin/data/converter/StringToBigIntegerConverter.java
@@ -21,6 +21,7 @@ import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
+import com.vaadin.data.ErrorMessageProvider;
import com.vaadin.data.Result;
import com.vaadin.data.ValueContext;
@@ -67,6 +68,37 @@ public class StringToBigIntegerConverter
super(emptyValue, errorMessage);
}
+ /**
+ * Creates a new converter instance with the given error message provider.
+ * Empty strings are converted to <code>null</code>.
+ *
+ * @param errorMessageProvider
+ * the error message provider to use if conversion fails
+ *
+ * @since
+ */
+ public StringToBigIntegerConverter(
+ ErrorMessageProvider errorMessageProvider) {
+ this(null, errorMessageProvider);
+ }
+
+ /**
+ * Creates a new converter instance with the given empty string value and
+ * error message provider.
+ *
+ * @param emptyValue
+ * the presentation value to return when converting an empty
+ * string, may be <code>null</code>
+ * @param errorMessageProvider
+ * the error message provider to use if conversion fails
+ *
+ * @since
+ */
+ public StringToBigIntegerConverter(BigInteger emptyValue,
+ ErrorMessageProvider errorMessageProvider) {
+ super(emptyValue, errorMessageProvider);
+ }
+
@Override
protected NumberFormat getFormat(Locale locale) {
NumberFormat numberFormat = super.getFormat(locale);
@@ -80,17 +112,16 @@ public class StringToBigIntegerConverter
@Override
public Result<BigInteger> convertToModel(String value,
ValueContext context) {
- return convertToNumber(value, context.getLocale().orElse(null))
- .map(number -> {
- if (number == null) {
- return null;
- }
- // Empty value will be a BigInteger
- if (number instanceof BigInteger) {
- return (BigInteger) number;
- }
- return ((BigDecimal) number).toBigInteger();
- });
+ return convertToNumber(value, context).map(number -> {
+ if (number == null) {
+ return null;
+ }
+ // Empty value will be a BigInteger
+ if (number instanceof BigInteger) {
+ return (BigInteger) number;
+ }
+ return ((BigDecimal) number).toBigInteger();
+ });
}
}
diff --git a/server/src/main/java/com/vaadin/data/converter/StringToBooleanConverter.java b/server/src/main/java/com/vaadin/data/converter/StringToBooleanConverter.java
index 49fa043a86..edb2908afa 100644
--- a/server/src/main/java/com/vaadin/data/converter/StringToBooleanConverter.java
+++ b/server/src/main/java/com/vaadin/data/converter/StringToBooleanConverter.java
@@ -19,13 +19,15 @@ package com.vaadin.data.converter;
import java.util.Locale;
import com.vaadin.data.Converter;
+import com.vaadin.data.ErrorMessageProvider;
import com.vaadin.data.Result;
import com.vaadin.data.ValueContext;
/**
* A converter that converts from {@link String} to {@link Boolean} and back.
* The String representation is given by {@link Boolean#toString()} or provided
- * in constructor {@link StringToBooleanConverter#StringToBooleanConverter(String, String, String)}.
+ * in constructor
+ * {@link StringToBooleanConverter#StringToBooleanConverter(String, String, String)}.
* <p>
* Leading and trailing white spaces are ignored when converting from a String.
* </p>
@@ -43,7 +45,7 @@ public class StringToBooleanConverter implements Converter<String, Boolean> {
private final String falseString;
- private String errorMessage;
+ private ErrorMessageProvider errorMessageProvider;
/**
* Creates converter with default string representations - "true" and
@@ -57,6 +59,20 @@ public class StringToBooleanConverter implements Converter<String, Boolean> {
}
/**
+ * Creates a new converter instance with the given error message provider.
+ * Empty strings are converted to <code>null</code>.
+ *
+ * @param errorMessageProvider
+ * the error message provider to use if conversion fails
+ *
+ * @since
+ */
+ public StringToBooleanConverter(ErrorMessageProvider errorMessageProvider) {
+ this(Boolean.TRUE.toString(), Boolean.FALSE.toString(),
+ errorMessageProvider);
+ }
+
+ /**
* Creates converter with custom string representation.
*
* @param errorMessage
@@ -68,7 +84,24 @@ public class StringToBooleanConverter implements Converter<String, Boolean> {
*/
public StringToBooleanConverter(String errorMessage, String trueString,
String falseString) {
- this.errorMessage = errorMessage;
+ this(trueString, falseString, ctx -> errorMessage);
+ }
+
+ /**
+ * Creates converter with custom string representation.
+ *
+ * @param falseString
+ * string representation for <code>false</code>
+ * @param trueString
+ * string representation for <code>true</code>
+ * @param errorMessageProvider
+ * the error message provider to use if conversion fails
+ *
+ * @since
+ */
+ public StringToBooleanConverter(String trueString, String falseString,
+ ErrorMessageProvider errorMessageProvider) {
+ this.errorMessageProvider = errorMessageProvider;
this.trueString = trueString;
this.falseString = falseString;
}
@@ -90,7 +123,7 @@ public class StringToBooleanConverter implements Converter<String, Boolean> {
} else if (value.isEmpty()) {
return Result.ok(null);
} else {
- return Result.error(errorMessage);
+ return Result.error(errorMessageProvider.apply(context));
}
}
diff --git a/server/src/main/java/com/vaadin/data/converter/StringToDoubleConverter.java b/server/src/main/java/com/vaadin/data/converter/StringToDoubleConverter.java
index 627775fbba..b1b11fdd1d 100644
--- a/server/src/main/java/com/vaadin/data/converter/StringToDoubleConverter.java
+++ b/server/src/main/java/com/vaadin/data/converter/StringToDoubleConverter.java
@@ -19,6 +19,7 @@ package com.vaadin.data.converter;
import java.text.NumberFormat;
import java.util.Locale;
+import com.vaadin.data.ErrorMessageProvider;
import com.vaadin.data.Result;
import com.vaadin.data.ValueContext;
@@ -64,10 +65,39 @@ public class StringToDoubleConverter
super(emptyValue, errorMessage);
}
+ /**
+ * Creates a new converter instance with the given error message provider.
+ * Empty strings are converted to <code>null</code>.
+ *
+ * @param errorMessageProvider
+ * the error message provider to use if conversion fails
+ *
+ * @since
+ */
+ public StringToDoubleConverter(ErrorMessageProvider errorMessageProvider) {
+ this(null, errorMessageProvider);
+ }
+
+ /**
+ * Creates a new converter instance with the given empty string value and
+ * error message provider.
+ *
+ * @param emptyValue
+ * the presentation value to return when converting an empty
+ * string, may be <code>null</code>
+ * @param errorMessageProvider
+ * the error message provider to use if conversion fails
+ *
+ * @since
+ */
+ public StringToDoubleConverter(Double emptyValue,
+ ErrorMessageProvider errorMessageProvider) {
+ super(emptyValue, errorMessageProvider);
+ }
+
@Override
public Result<Double> convertToModel(String value, ValueContext context) {
- Result<Number> n = convertToNumber(value,
- context.getLocale().orElse(null));
+ Result<Number> n = convertToNumber(value, context);
return n.map(number -> {
if (number == null) {
diff --git a/server/src/main/java/com/vaadin/data/converter/StringToFloatConverter.java b/server/src/main/java/com/vaadin/data/converter/StringToFloatConverter.java
index 37e159f844..62c211a2ad 100644
--- a/server/src/main/java/com/vaadin/data/converter/StringToFloatConverter.java
+++ b/server/src/main/java/com/vaadin/data/converter/StringToFloatConverter.java
@@ -19,6 +19,7 @@ package com.vaadin.data.converter;
import java.text.NumberFormat;
import java.util.Locale;
+import com.vaadin.data.ErrorMessageProvider;
import com.vaadin.data.Result;
import com.vaadin.data.ValueContext;
@@ -62,10 +63,39 @@ public class StringToFloatConverter
super(emptyValue, errorMessage);
}
+ /**
+ * Creates a new converter instance with the given error message provider.
+ * Empty strings are converted to <code>null</code>.
+ *
+ * @param errorMessageProvider
+ * the error message provider to use if conversion fails
+ *
+ * @since
+ */
+ public StringToFloatConverter(ErrorMessageProvider errorMessageProvider) {
+ this(null, errorMessageProvider);
+ }
+
+ /**
+ * Creates a new converter instance with the given empty string value and
+ * error message provider.
+ *
+ * @param emptyValue
+ * the presentation value to return when converting an empty
+ * string, may be <code>null</code>
+ * @param errorMessageProvider
+ * the error message provider to use if conversion fails
+ *
+ * @since
+ */
+ public StringToFloatConverter(Float emptyValue,
+ ErrorMessageProvider errorMessageProvider) {
+ super(emptyValue, errorMessageProvider);
+ }
+
@Override
public Result<Float> convertToModel(String value, ValueContext context) {
- Result<Number> n = convertToNumber(value,
- context.getLocale().orElse(null));
+ Result<Number> n = convertToNumber(value, context);
return n.map(number -> {
if (number == null) {
diff --git a/server/src/main/java/com/vaadin/data/converter/StringToIntegerConverter.java b/server/src/main/java/com/vaadin/data/converter/StringToIntegerConverter.java
index 88f2c29126..b0a9449a56 100644
--- a/server/src/main/java/com/vaadin/data/converter/StringToIntegerConverter.java
+++ b/server/src/main/java/com/vaadin/data/converter/StringToIntegerConverter.java
@@ -19,6 +19,7 @@ package com.vaadin.data.converter;
import java.text.NumberFormat;
import java.util.Locale;
+import com.vaadin.data.ErrorMessageProvider;
import com.vaadin.data.Result;
import com.vaadin.data.ValueContext;
@@ -62,6 +63,36 @@ public class StringToIntegerConverter
}
/**
+ * Creates a new converter instance with the given error message provider.
+ * Empty strings are converted to <code>null</code>.
+ *
+ * @param errorMessageProvider
+ * the error message provider to use if conversion fails
+ *
+ * @since
+ */
+ public StringToIntegerConverter(ErrorMessageProvider errorMessageProvider) {
+ this(null, errorMessageProvider);
+ }
+
+ /**
+ * Creates a new converter instance with the given empty string value and
+ * error message provider.
+ *
+ * @param emptyValue
+ * the presentation value to return when converting an empty
+ * string, may be <code>null</code>
+ * @param errorMessageProvider
+ * the error message provider to use if conversion fails
+ *
+ * @since
+ */
+ public StringToIntegerConverter(Integer emptyValue,
+ ErrorMessageProvider errorMessageProvider) {
+ super(emptyValue, errorMessageProvider);
+ }
+
+ /**
* Returns the format used by
* {@link #convertToPresentation(Object, ValueContext)} and
* {@link #convertToModel(String, ValueContext)}.
@@ -80,8 +111,7 @@ public class StringToIntegerConverter
@Override
public Result<Integer> convertToModel(String value, ValueContext context) {
- Result<Number> n = convertToNumber(value,
- context.getLocale().orElse(null));
+ Result<Number> n = convertToNumber(value, context);
return n.flatMap(number -> {
if (number == null) {
return Result.ok(null);
@@ -94,7 +124,7 @@ public class StringToIntegerConverter
// long and thus does not need to consider wrap-around.
return Result.ok(intValue);
}
- return Result.error(getErrorMessage());
+ return Result.error(getErrorMessage(context));
});
}
diff --git a/server/src/main/java/com/vaadin/data/converter/StringToLongConverter.java b/server/src/main/java/com/vaadin/data/converter/StringToLongConverter.java
index 4e65296316..39ef8f777a 100644
--- a/server/src/main/java/com/vaadin/data/converter/StringToLongConverter.java
+++ b/server/src/main/java/com/vaadin/data/converter/StringToLongConverter.java
@@ -19,6 +19,7 @@ package com.vaadin.data.converter;
import java.text.NumberFormat;
import java.util.Locale;
+import com.vaadin.data.ErrorMessageProvider;
import com.vaadin.data.Result;
import com.vaadin.data.ValueContext;
@@ -62,6 +63,36 @@ public class StringToLongConverter
}
/**
+ * Creates a new converter instance with the given error message provider.
+ * Empty strings are converted to <code>null</code>.
+ *
+ * @param errorMessageProvider
+ * the error message provider to use if conversion fails
+ *
+ * @since
+ */
+ public StringToLongConverter(ErrorMessageProvider errorMessageProvider) {
+ this(null, errorMessageProvider);
+ }
+
+ /**
+ * Creates a new converter instance with the given empty string value and
+ * error message provider.
+ *
+ * @param emptyValue
+ * the presentation value to return when converting an empty
+ * string, may be <code>null</code>
+ * @param errorMessageProvider
+ * the error message provider to use if conversion fails
+ *
+ * @since
+ */
+ public StringToLongConverter(Long emptyValue,
+ ErrorMessageProvider errorMessageProvider) {
+ super(emptyValue, errorMessageProvider);
+ }
+
+ /**
* Returns the format used by
* {@link #convertToPresentation(Object, ValueContext)} and
* {@link #convertToModel(String, ValueContext)}.
@@ -80,8 +111,7 @@ public class StringToLongConverter
@Override
public Result<Long> convertToModel(String value, ValueContext context) {
- Result<Number> n = convertToNumber(value,
- context.getLocale().orElse(null));
+ Result<Number> n = convertToNumber(value, context);
return n.map(number -> {
if (number == null) {
return null;
diff --git a/server/src/test/java/com/vaadin/data/BinderTest.java b/server/src/test/java/com/vaadin/data/BinderTest.java
index abbbe541ae..ef52ea8ef5 100644
--- a/server/src/test/java/com/vaadin/data/BinderTest.java
+++ b/server/src/test/java/com/vaadin/data/BinderTest.java
@@ -1102,4 +1102,27 @@ public class BinderTest extends BinderTestBase<Binder<Person>, Person> {
assertTrue("Binding should be readonly", binding.isReadOnly());
assertTrue("Name field should be readonly", nameField.isReadOnly());
}
+
+ @Test
+ public void conversionWithLocaleBasedErrorMessage() {
+ String fiError = "VIRHE";
+ String otherError = "ERROR";
+
+ binder.forField(ageField).withConverter(new StringToIntegerConverter(
+ context -> context.getLocale().map(Locale::getLanguage)
+ .orElse("en").equals("fi") ? fiError : otherError))
+ .bind(Person::getAge, Person::setAge);
+
+ binder.setBean(item);
+
+ ageField.setValue("not a number");
+
+ assertEquals(otherError,
+ ageField.getErrorMessage().getFormattedHtmlMessage());
+ ageField.setLocale(new Locale("fi"));
+ // Re-validate to get the error message with correct locale
+ binder.validate();
+ assertEquals(fiError,
+ ageField.getErrorMessage().getFormattedHtmlMessage());
+ }
}