@@ -36,24 +36,32 @@ import com.vaadin.data.ValueContext; | |||
* @author Vaadin Ltd | |||
* @since 8.0 | |||
*/ | |||
public abstract class AbstractStringToNumberConverter<T> | |||
public abstract class AbstractStringToNumberConverter<T extends Number> | |||
implements Converter<String, T> { | |||
private final String errorMessage; | |||
private T emptyValue; | |||
/** | |||
* Creates a new converter instance with the given error message. | |||
* Creates a new converter instance with the given empty string value and | |||
* error message. | |||
* | |||
* @param emptyValue | |||
* the presentation value to return when converting an empty | |||
* string, may be <code>null</code> | |||
* @param errorMessage | |||
* the error message to use if conversion fails | |||
*/ | |||
protected AbstractStringToNumberConverter(String errorMessage) { | |||
protected AbstractStringToNumberConverter(T emptyValue, | |||
String errorMessage) { | |||
this.emptyValue = emptyValue; | |||
this.errorMessage = errorMessage; | |||
} | |||
/** | |||
* Returns the format used by {@link #convertToPresentation(Object, ValueContext)} | |||
* and {@link #convertToModel(Object, ValueContext)}. | |||
* Returns the format used by | |||
* {@link #convertToPresentation(Object, ValueContext)} and | |||
* {@link #convertToModel(Object, ValueContext)}. | |||
* | |||
* @param locale | |||
* The locale to use | |||
@@ -94,8 +102,8 @@ public abstract class AbstractStringToNumberConverter<T> | |||
} | |||
if (parsedValue == null) { | |||
// Convert "" to null | |||
return Result.ok(null); | |||
// Convert "" to the empty value | |||
return Result.ok(emptyValue); | |||
} | |||
return Result.ok(parsedValue); |
@@ -41,13 +41,29 @@ public class StringToBigDecimalConverter | |||
extends AbstractStringToNumberConverter<BigDecimal> { | |||
/** | |||
* Creates a new converter instance with the given error message. | |||
* Creates a new converter instance with the given error message. Empty | |||
* strings are converted to <code>null</code>. | |||
* | |||
* @param errorMessage | |||
* the error message to use if conversion fails | |||
*/ | |||
public StringToBigDecimalConverter(String errorMessage) { | |||
super(errorMessage); | |||
this(null, errorMessage); | |||
} | |||
/** | |||
* Creates a new converter instance with the given empty string value and | |||
* error message. | |||
* | |||
* @param emptyValue | |||
* the presentation value to return when converting an empty | |||
* string, may be <code>null</code> | |||
* @param errorMessage | |||
* the error message to use if conversion fails | |||
*/ | |||
public StringToBigDecimalConverter(BigDecimal emptyValue, | |||
String errorMessage) { | |||
super(emptyValue, errorMessage); | |||
} | |||
@Override |
@@ -40,14 +40,31 @@ import com.vaadin.data.ValueContext; | |||
*/ | |||
public class StringToBigIntegerConverter | |||
extends AbstractStringToNumberConverter<BigInteger> { | |||
/** | |||
* Creates a new converter instance with the given error message. | |||
* Creates a new converter instance with the given error message. Empty | |||
* strings are converted to <code>null</code>. | |||
* | |||
* @param errorMessage | |||
* the error message to use if conversion fails | |||
*/ | |||
public StringToBigIntegerConverter(String errorMessage) { | |||
super(errorMessage); | |||
this(null, errorMessage); | |||
} | |||
/** | |||
* Creates a new converter instance with the given empty string value and | |||
* error message. | |||
* | |||
* @param emptyValue | |||
* the presentation value to return when converting an empty | |||
* string, may be <code>null</code> | |||
* @param errorMessage | |||
* the error message to use if conversion fails | |||
*/ | |||
public StringToBigIntegerConverter(BigInteger emptyValue, | |||
String errorMessage) { | |||
super(emptyValue, errorMessage); | |||
} | |||
@Override | |||
@@ -68,6 +85,10 @@ public class StringToBigIntegerConverter | |||
if (number == null) { | |||
return null; | |||
} else { | |||
// Empty value will be a BigInteger | |||
if (number instanceof BigInteger) { | |||
return (BigInteger) number; | |||
} | |||
return ((BigDecimal) number).toBigInteger(); | |||
} | |||
}); |
@@ -40,13 +40,28 @@ public class StringToDoubleConverter | |||
extends AbstractStringToNumberConverter<Double> { | |||
/** | |||
* Creates a new converter instance with the given error message. | |||
* Creates a new converter instance with the given error message. Empty | |||
* strings are converted to <code>null</code>. | |||
* | |||
* @param errorMessage | |||
* the error message to use if conversion fails | |||
*/ | |||
public StringToDoubleConverter(String errorMessage) { | |||
super(errorMessage); | |||
this(null, errorMessage); | |||
} | |||
/** | |||
* Creates a new converter instance with the given empty string value and | |||
* error message. | |||
* | |||
* @param emptyValue | |||
* the presentation value to return when converting an empty | |||
* string, may be <code>null</code> | |||
* @param errorMessage | |||
* the error message to use if conversion fails | |||
*/ | |||
public StringToDoubleConverter(Double emptyValue, String errorMessage) { | |||
super(emptyValue, errorMessage); | |||
} | |||
@Override |
@@ -38,13 +38,28 @@ public class StringToFloatConverter | |||
extends AbstractStringToNumberConverter<Float> { | |||
/** | |||
* Creates a new converter instance with the given error message. | |||
* Creates a new converter instance with the given error message. Empty | |||
* strings are converted to <code>null</code>. | |||
* | |||
* @param errorMessage | |||
* the error message to use if conversion fails | |||
*/ | |||
public StringToFloatConverter(String errorMessage) { | |||
super(errorMessage); | |||
this(null, errorMessage); | |||
} | |||
/** | |||
* Creates a new converter instance with the given empty string value and | |||
* error message. | |||
* | |||
* @param emptyValue | |||
* the presentation value to return when converting an empty | |||
* string, may be <code>null</code> | |||
* @param errorMessage | |||
* the error message to use if conversion fails | |||
*/ | |||
public StringToFloatConverter(Float emptyValue, String errorMessage) { | |||
super(emptyValue, errorMessage); | |||
} | |||
@Override |
@@ -37,18 +37,33 @@ public class StringToIntegerConverter | |||
extends AbstractStringToNumberConverter<Integer> { | |||
/** | |||
* Creates a new converter instance with the given error message. | |||
* Creates a new converter instance with the given error message. Empty | |||
* strings are converted to <code>null</code>. | |||
* | |||
* @param errorMessage | |||
* the error message to use if conversion fails | |||
*/ | |||
public StringToIntegerConverter(String errorMessage) { | |||
super(errorMessage); | |||
this(null, errorMessage); | |||
} | |||
/** | |||
* Creates a new converter instance with the given empty string value and | |||
* error message. | |||
* | |||
* @param emptyValue | |||
* the presentation value to return when converting an empty | |||
* string, may be <code>null</code> | |||
* @param errorMessage | |||
* the error message to use if conversion fails | |||
*/ | |||
public StringToIntegerConverter(Integer emptyValue, String errorMessage) { | |||
super(emptyValue, errorMessage); | |||
} | |||
/** | |||
* Returns the format used by | |||
* {@link #convertToPresentation(Object, ValueContext)} and | |||
* {@link #convertToPresentation(Object, ValueContext)} and | |||
* {@link #convertToModel(String, ValueContext)}. | |||
* | |||
* @param locale |
@@ -37,18 +37,34 @@ public class StringToLongConverter | |||
extends AbstractStringToNumberConverter<Long> { | |||
/** | |||
* Creates a new converter instance with the given error message. | |||
* Creates a new converter instance with the given error message. Empty | |||
* strings are converted to <code>null</code>. | |||
* | |||
* @param errorMessage | |||
* the error message to use if conversion fails | |||
*/ | |||
public StringToLongConverter(String errorMessage) { | |||
super(errorMessage); | |||
this(null, errorMessage); | |||
} | |||
/** | |||
* Returns the format used by {@link #convertToPresentation(Object, ValueContext)} | |||
* and {@link #convertToModel(String, ValueContext)}. | |||
* Creates a new converter instance with the given empty string value and | |||
* error message. | |||
* | |||
* @param emptyValue | |||
* the presentation value to return when converting an empty | |||
* string, may be <code>null</code> | |||
* @param errorMessage | |||
* the error message to use if conversion fails | |||
*/ | |||
public StringToLongConverter(Long emptyValue, String errorMessage) { | |||
super(emptyValue, errorMessage); | |||
} | |||
/** | |||
* Returns the format used by | |||
* {@link #convertToPresentation(Object, ValueContext)} and | |||
* {@link #convertToModel(String, ValueContext)}. | |||
* | |||
* @param locale | |||
* The locale to use |
@@ -17,22 +17,23 @@ public abstract class AbstractConverterTest { | |||
protected abstract Converter<?, ?> getConverter(); | |||
protected void assertValue(Object object, Result<?> result) { | |||
assertValue(null, object, result); | |||
protected <T> void assertValue(T expectedValue, Result<?> result) { | |||
assertValue(null, expectedValue, result); | |||
} | |||
protected void assertValue(String error, Object object, Result<?> result) { | |||
protected <T> void assertValue(String assertMessage, T expectedValue, | |||
Result<?> result) { | |||
Assert.assertNotNull("Result should never be null", result); | |||
Assert.assertFalse("Result is not ok", result.isError()); | |||
Assert.assertEquals(object, | |||
Assert.assertEquals(expectedValue, | |||
result.getOrThrow(message -> new AssertionError( | |||
error != null ? error : message))); | |||
assertMessage != null ? assertMessage : message))); | |||
} | |||
protected void assertError(String expected, Result<?> result) { | |||
protected void assertError(String expectedResultMessage, Result<?> result) { | |||
Assert.assertNotNull("Result should never be null", result); | |||
Assert.assertTrue("Result should be an error", result.isError()); | |||
Assert.assertEquals(expected, result.getMessage().get()); | |||
Assert.assertEquals(expectedResultMessage, result.getMessage().get()); | |||
} | |||
protected String getErrorMessage() { |
@@ -50,4 +50,15 @@ public class StringToBigDecimalConverterTest | |||
new ValueContext(Locale.GERMAN)); | |||
Assert.assertEquals(expected, converted); | |||
} | |||
@Test | |||
public void customEmptyValue() { | |||
StringToBigDecimalConverter converter = new StringToBigDecimalConverter( | |||
BigDecimal.ZERO, getErrorMessage()); | |||
assertValue(BigDecimal.ZERO, | |||
converter.convertToModel("", new ValueContext())); | |||
Assert.assertEquals("0", converter | |||
.convertToPresentation(BigDecimal.ZERO, new ValueContext())); | |||
} | |||
} |
@@ -54,4 +54,16 @@ public class StringToBigIntegerConverterTest | |||
"Value with specific locale was converted incorrectly", | |||
expected, converted); | |||
} | |||
@Test | |||
public void customEmptyValue() { | |||
StringToBigIntegerConverter converter = new StringToBigIntegerConverter( | |||
BigInteger.ZERO, getErrorMessage()); | |||
assertValue(BigInteger.ZERO, | |||
converter.convertToModel("", new ValueContext())); | |||
Assert.assertEquals("0", converter | |||
.convertToPresentation(BigInteger.ZERO, new ValueContext())); | |||
} | |||
} |
@@ -35,4 +35,14 @@ public class StringToDoubleConverterTest extends AbstractConverterTest { | |||
Assert.assertEquals("Failed", result.getMessage().get()); | |||
} | |||
@Test | |||
public void customEmptyValue() { | |||
StringToDoubleConverter converter = new StringToDoubleConverter(0.0, | |||
getErrorMessage()); | |||
assertValue(0.0, converter.convertToModel("", new ValueContext())); | |||
Assert.assertEquals("0", | |||
converter.convertToPresentation(0.0, new ValueContext())); | |||
} | |||
} |
@@ -1,5 +1,6 @@ | |||
package com.vaadin.tests.data.converter; | |||
import org.junit.Assert; | |||
import org.junit.Test; | |||
import com.vaadin.data.ValueContext; | |||
@@ -31,4 +32,15 @@ public class StringToFloatConverterTest extends AbstractStringConverterTest { | |||
assertValue(Float.valueOf(10), | |||
getConverter().convertToModel("10", new ValueContext())); | |||
} | |||
@Test | |||
public void customEmptyValue() { | |||
StringToFloatConverter converter = new StringToFloatConverter( | |||
(float) 0.0, getErrorMessage()); | |||
assertValue((float) 0.0, | |||
converter.convertToModel("", new ValueContext())); | |||
Assert.assertEquals("0", converter.convertToPresentation((float) 0.0, | |||
new ValueContext())); | |||
} | |||
} |
@@ -51,4 +51,14 @@ public class StringToIntegerConverterTest extends AbstractConverterTest { | |||
Assert.assertTrue(result.isError()); | |||
Assert.assertEquals("Failed", result.getMessage().get()); | |||
} | |||
@Test | |||
public void customEmptyValue() { | |||
StringToIntegerConverter converter = new StringToIntegerConverter(0, | |||
getErrorMessage()); | |||
assertValue(0, converter.convertToModel("", new ValueContext())); | |||
Assert.assertEquals("0", | |||
converter.convertToPresentation(0, new ValueContext())); | |||
} | |||
} |
@@ -1,5 +1,6 @@ | |||
package com.vaadin.tests.data.converter; | |||
import org.junit.Assert; | |||
import org.junit.Test; | |||
import com.vaadin.data.Result; | |||
@@ -48,4 +49,14 @@ public class StringToLongConverterTest extends AbstractStringConverterTest { | |||
assertValue(Long.MIN_VALUE, l); | |||
} | |||
@Test | |||
public void customEmptyValue() { | |||
StringToLongConverter converter = new StringToLongConverter((long) 0, | |||
getErrorMessage()); | |||
assertValue((long) 0, converter.convertToModel("", new ValueContext())); | |||
Assert.assertEquals("0", | |||
converter.convertToPresentation((long) 0, new ValueContext())); | |||
} | |||
} |