Initial support for JSR-354 Money & Currency

Issue: SPR-12209
This commit is contained in:
Juergen Hoeller
2015-03-13 19:40:00 +01:00
parent bc6a98c144
commit 6c169bd644
25 changed files with 878 additions and 204 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -43,10 +43,11 @@ import static org.junit.Assert.*;
*/
public class DateFormatterTests {
private static final TimeZone UTC = TimeZone.getTimeZone("UTC");
@Rule
public ExpectedException thown = ExpectedException.none();
private static final TimeZone UTC = TimeZone.getTimeZone("UTC");
@Test
public void shouldPrintAndParseDefault() throws Exception {
@@ -210,12 +211,12 @@ public class DateFormatterTests {
assertThat("uses style", formatter.print(date, Locale.US), is("6/1/09"));
}
private Date getDate(int year, int month, int dayOfMonth) {
return getDate(year, month, dayOfMonth, 0, 0, 0, 0);
}
private Date getDate(int year, int month, int dayOfMonth, int hour, int minute,
int second, int millisecond) {
private Date getDate(int year, int month, int dayOfMonth, int hour, int minute, int second, int millisecond) {
Calendar cal = Calendar.getInstance(Locale.US);
cal.setTimeZone(UTC);
cal.clear();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -46,10 +46,11 @@ import static org.junit.Assert.*;
*/
public class DateFormattingTests {
private FormattingConversionService conversionService = new FormattingConversionService();
private final FormattingConversionService conversionService = new FormattingConversionService();
private DataBinder binder;
@Before
public void setUp() {
DateFormatterRegistrar registrar = new DateFormatterRegistrar();
@@ -73,6 +74,7 @@ public class DateFormattingTests {
LocaleContextHolder.setLocale(null);
}
@Test
public void testBindDate() {
MutablePropertyValues propertyValues = new MutablePropertyValues();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,9 +28,10 @@ import static org.junit.Assert.*;
/**
* @author Keith Donald
*/
public class CurrencyFormatterTests {
public class CurrencyStyleFormatterTests {
private final CurrencyStyleFormatter formatter = new CurrencyStyleFormatter();
private CurrencyFormatter formatter = new CurrencyFormatter();
@Test
public void formatValue() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,10 +41,11 @@ import static org.junit.Assert.*;
*/
public class NumberFormattingTests {
private FormattingConversionService conversionService = new FormattingConversionService();
private final FormattingConversionService conversionService = new FormattingConversionService();
private DataBinder binder;
@Before
public void setUp() {
DefaultConversionService.addDefaultConverters(conversionService);
@@ -53,12 +54,13 @@ public class NumberFormattingTests {
public String resolveStringValue(String strVal) {
if ("${pattern}".equals(strVal)) {
return "#,##.00";
} else {
}
else {
return strVal;
}
}
});
conversionService.addFormatterForFieldType(Number.class, new NumberFormatter());
conversionService.addFormatterForFieldType(Number.class, new NumberStyleFormatter());
conversionService.addFormatterForFieldAnnotation(new NumberFormatAnnotationFormatterFactory());
LocaleContextHolder.setLocale(Locale.US);
binder = new DataBinder(new TestBean());
@@ -70,6 +72,7 @@ public class NumberFormattingTests {
LocaleContextHolder.setLocale(null);
}
@Test
public void testDefaultNumberFormatting() {
MutablePropertyValues propertyValues = new MutablePropertyValues();
@@ -172,6 +175,7 @@ public class NumberFormattingTests {
assertEquals("1,25.00,2,35.00", binder.getBindingResult().getFieldValue("patternList2"));
}
@SuppressWarnings("unused")
private static class TestBean {
@@ -261,7 +265,6 @@ public class NumberFormattingTests {
public void setPatternList2(List<BigDecimal> patternList2) {
this.patternList2 = patternList2;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,9 +27,10 @@ import static org.junit.Assert.*;
/**
* @author Keith Donald
*/
public class NumberFormatterTests {
public class NumberStyleFormatterTests {
private final NumberStyleFormatter formatter = new NumberStyleFormatter();
private NumberFormatter formatter = new NumberFormatter();
@Test
public void formatValue() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,9 +27,10 @@ import static org.junit.Assert.*;
/**
* @author Keith Donald
*/
public class PercentFormatterTests {
public class PercentStyleFormatterTests {
private final PercentStyleFormatter formatter = new PercentStyleFormatter();
private PercentFormatter formatter = new PercentFormatter();
@Test
public void formatValue() {
@@ -38,8 +39,7 @@ public class PercentFormatterTests {
@Test
public void parseValue() throws ParseException {
assertEquals(new BigDecimal(".2356"), formatter.parse("23.56%",
Locale.US));
assertEquals(new BigDecimal(".2356"), formatter.parse("23.56%", Locale.US));
}
@Test(expected = ParseException.class)

View File

@@ -0,0 +1,244 @@
/*
* Copyright 2002-2015 the original author or authors.
*
* 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 org.springframework.format.number.money;
import java.util.Locale;
import javax.money.CurrencyUnit;
import javax.money.MonetaryAmount;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.format.annotation.NumberFormat;
import org.springframework.format.support.DefaultFormattingConversionService;
import org.springframework.format.support.FormattingConversionService;
import org.springframework.validation.DataBinder;
import static org.junit.Assert.*;
/**
* @author Juergen Hoeller
* @since 4.2
*/
public class MoneyFormattingTests {
private final FormattingConversionService conversionService = new DefaultFormattingConversionService();
@Before
public void setUp() {
LocaleContextHolder.setLocale(Locale.US);
}
@After
public void tearDown() {
LocaleContextHolder.setLocale(null);
}
@Test
public void testAmountAndUnit() {
DataBinder binder = new DataBinder(new MoneyHolder());
binder.setConversionService(conversionService);
MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.add("amount", "USD 10.50");
propertyValues.add("unit", "USD");
binder.bind(propertyValues);
assertEquals(0, binder.getBindingResult().getErrorCount());
assertEquals("USD10.50", binder.getBindingResult().getFieldValue("amount"));
assertEquals("USD", binder.getBindingResult().getFieldValue("unit"));
}
@Test
public void testAmountWithNumberFormat1() {
DataBinder binder = new DataBinder(new FormattedMoneyHolder1());
binder.setConversionService(conversionService);
MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.add("amount", "$10.50");
binder.bind(propertyValues);
assertEquals(0, binder.getBindingResult().getErrorCount());
assertEquals("$10.50", binder.getBindingResult().getFieldValue("amount"));
/* TODO: preserve currency from given value
LocaleContextHolder.setLocale(Locale.CANADA);
binder.bind(propertyValues);
LocaleContextHolder.setLocale(Locale.US);
assertEquals(0, binder.getBindingResult().getErrorCount());
assertEquals("$10.50", binder.getBindingResult().getFieldValue("amount"));
*/
}
@Test
public void testAmountWithNumberFormat2() {
DataBinder binder = new DataBinder(new FormattedMoneyHolder2());
binder.setConversionService(conversionService);
MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.add("amount", "10.50");
binder.bind(propertyValues);
assertEquals(0, binder.getBindingResult().getErrorCount());
assertEquals("10.5", binder.getBindingResult().getFieldValue("amount"));
}
@Test
public void testAmountWithNumberFormat3() {
DataBinder binder = new DataBinder(new FormattedMoneyHolder3());
binder.setConversionService(conversionService);
MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.add("amount", "10%");
binder.bind(propertyValues);
assertEquals(0, binder.getBindingResult().getErrorCount());
assertEquals("10%", binder.getBindingResult().getFieldValue("amount"));
}
@Test
public void testAmountWithNumberFormat4() {
DataBinder binder = new DataBinder(new FormattedMoneyHolder4());
binder.setConversionService(conversionService);
MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.add("amount", "010.500");
binder.bind(propertyValues);
assertEquals(0, binder.getBindingResult().getErrorCount());
assertEquals("010.500", binder.getBindingResult().getFieldValue("amount"));
}
@Test
public void testAmountWithNumberFormat5() {
DataBinder binder = new DataBinder(new FormattedMoneyHolder5());
binder.setConversionService(conversionService);
MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.add("amount", "$ 10.50");
binder.bind(propertyValues);
assertEquals(0, binder.getBindingResult().getErrorCount());
assertEquals("$ 010.500", binder.getBindingResult().getFieldValue("amount"));
/* TODO: preserve currency from given value
LocaleContextHolder.setLocale(Locale.CANADA);
binder.bind(propertyValues);
LocaleContextHolder.setLocale(Locale.US);
assertEquals(0, binder.getBindingResult().getErrorCount());
assertEquals("$ 010.500", binder.getBindingResult().getFieldValue("amount"));
*/
}
public static class MoneyHolder {
private MonetaryAmount amount;
private CurrencyUnit unit;
public MonetaryAmount getAmount() {
return amount;
}
public void setAmount(MonetaryAmount amount) {
this.amount = amount;
}
public CurrencyUnit getUnit() {
return unit;
}
public void setUnit(CurrencyUnit unit) {
this.unit = unit;
}
}
public static class FormattedMoneyHolder1 {
@NumberFormat
private MonetaryAmount amount;
public MonetaryAmount getAmount() {
return amount;
}
public void setAmount(MonetaryAmount amount) {
this.amount = amount;
}
}
public static class FormattedMoneyHolder2 {
@NumberFormat(style = NumberFormat.Style.NUMBER)
private MonetaryAmount amount;
public MonetaryAmount getAmount() {
return amount;
}
public void setAmount(MonetaryAmount amount) {
this.amount = amount;
}
}
public static class FormattedMoneyHolder3 {
@NumberFormat(style = NumberFormat.Style.PERCENT)
private MonetaryAmount amount;
public MonetaryAmount getAmount() {
return amount;
}
public void setAmount(MonetaryAmount amount) {
this.amount = amount;
}
}
public static class FormattedMoneyHolder4 {
@NumberFormat(pattern = "#000.000#")
private MonetaryAmount amount;
public MonetaryAmount getAmount() {
return amount;
}
public void setAmount(MonetaryAmount amount) {
this.amount = amount;
}
}
public static class FormattedMoneyHolder5 {
@NumberFormat(pattern = "\u00A4 #000.000#")
private MonetaryAmount amount;
public MonetaryAmount getAmount() {
return amount;
}
public void setAmount(MonetaryAmount amount) {
this.amount = amount;
}
}
}

View File

@@ -28,7 +28,6 @@ import java.util.Properties;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -53,7 +52,7 @@ import org.springframework.format.annotation.NumberFormat;
import org.springframework.format.datetime.joda.DateTimeParser;
import org.springframework.format.datetime.joda.JodaDateTimeFormatAnnotationFormatterFactory;
import org.springframework.format.datetime.joda.ReadablePartialPrinter;
import org.springframework.format.number.NumberFormatter;
import org.springframework.format.number.NumberStyleFormatter;
import static org.junit.Assert.*;
@@ -67,6 +66,7 @@ public class FormattingConversionServiceTests {
private FormattingConversionService formattingService;
@Before
public void setUp() {
formattingService = new FormattingConversionService();
@@ -79,9 +79,10 @@ public class FormattingConversionServiceTests {
LocaleContextHolder.setLocale(null);
}
@Test
public void testFormatFieldForTypeWithFormatter() throws ParseException {
formattingService.addFormatterForFieldType(Number.class, new NumberFormatter());
formattingService.addFormatterForFieldType(Number.class, new NumberStyleFormatter());
String formatted = formattingService.convert(3, String.class);
assertEquals("3", formatted);
Integer i = formattingService.convert("3", Integer.class);
@@ -239,26 +240,26 @@ public class FormattingConversionServiceTests {
@Test
public void testPrintNull() throws ParseException {
formattingService.addFormatterForFieldType(Number.class, new NumberFormatter());
formattingService.addFormatterForFieldType(Number.class, new NumberStyleFormatter());
assertEquals("", formattingService.convert(null, TypeDescriptor.valueOf(Integer.class), TypeDescriptor.valueOf(String.class)));
}
@Test
public void testParseNull() throws ParseException {
formattingService.addFormatterForFieldType(Number.class, new NumberFormatter());
formattingService.addFormatterForFieldType(Number.class, new NumberStyleFormatter());
assertNull(formattingService
.convert(null, TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class)));
}
@Test
public void testParseEmptyString() throws ParseException {
formattingService.addFormatterForFieldType(Number.class, new NumberFormatter());
formattingService.addFormatterForFieldType(Number.class, new NumberStyleFormatter());
assertNull(formattingService.convert("", TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class)));
}
@Test
public void testParseBlankString() throws ParseException {
formattingService.addFormatterForFieldType(Number.class, new NumberFormatter());
formattingService.addFormatterForFieldType(Number.class, new NumberStyleFormatter());
assertNull(formattingService.convert(" ", TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class)));
}
@@ -270,7 +271,7 @@ public class FormattingConversionServiceTests {
@Test(expected=ConversionFailedException.class)
public void testParseNullPrimitiveProperty() throws ParseException {
formattingService.addFormatterForFieldType(Integer.class, new NumberFormatter());
formattingService.addFormatterForFieldType(Integer.class, new NumberStyleFormatter());
assertNull(formattingService.convert(null, TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(int.class)));
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -48,7 +48,7 @@ import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.context.support.StaticMessageSource;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.format.Formatter;
import org.springframework.format.number.NumberFormatter;
import org.springframework.format.number.NumberStyleFormatter;
import org.springframework.format.support.FormattingConversionService;
import org.springframework.tests.sample.beans.BeanWithObjectProperty;
import org.springframework.tests.sample.beans.DerivedTestBean;
@@ -332,7 +332,7 @@ public class DataBinderTests extends TestCase {
DataBinder binder = new DataBinder(tb);
FormattingConversionService conversionService = new FormattingConversionService();
DefaultConversionService.addDefaultConverters(conversionService);
conversionService.addFormatterForFieldType(Float.class, new NumberFormatter());
conversionService.addFormatterForFieldType(Float.class, new NumberStyleFormatter());
binder.setConversionService(conversionService);
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.add("myFloat", "1,2");
@@ -363,7 +363,7 @@ public class DataBinderTests extends TestCase {
DataBinder binder = new DataBinder(tb);
FormattingConversionService conversionService = new FormattingConversionService();
DefaultConversionService.addDefaultConverters(conversionService);
conversionService.addFormatterForFieldType(Float.class, new NumberFormatter());
conversionService.addFormatterForFieldType(Float.class, new NumberStyleFormatter());
binder.setConversionService(conversionService);
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.add("myFloat", "1x2");
@@ -409,7 +409,7 @@ public class DataBinderTests extends TestCase {
DataBinder binder = new DataBinder(tb);
FormattingConversionService conversionService = new FormattingConversionService();
DefaultConversionService.addDefaultConverters(conversionService);
conversionService.addFormatterForFieldType(Float.class, new NumberFormatter());
conversionService.addFormatterForFieldType(Float.class, new NumberStyleFormatter());
binder.setConversionService(conversionService);
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.add("integerList[0]", "1");
@@ -430,7 +430,7 @@ public class DataBinderTests extends TestCase {
DataBinder binder = new DataBinder(tb);
FormattingConversionService conversionService = new FormattingConversionService();
DefaultConversionService.addDefaultConverters(conversionService);
conversionService.addFormatterForFieldType(Float.class, new NumberFormatter());
conversionService.addFormatterForFieldType(Float.class, new NumberStyleFormatter());
binder.setConversionService(conversionService);
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.add("integerList[0]", "1x2");
@@ -452,7 +452,7 @@ public class DataBinderTests extends TestCase {
DataBinder binder = new DataBinder(tb);
FormattingConversionService conversionService = new FormattingConversionService();
DefaultConversionService.addDefaultConverters(conversionService);
conversionService.addFormatterForFieldType(Float.class, new NumberFormatter());
conversionService.addFormatterForFieldType(Float.class, new NumberStyleFormatter());
binder.setConversionService(conversionService);
binder.initDirectFieldAccess();
MutablePropertyValues pvs = new MutablePropertyValues();
@@ -485,7 +485,7 @@ public class DataBinderTests extends TestCase {
binder.initDirectFieldAccess();
FormattingConversionService conversionService = new FormattingConversionService();
DefaultConversionService.addDefaultConverters(conversionService);
conversionService.addFormatterForFieldType(Float.class, new NumberFormatter());
conversionService.addFormatterForFieldType(Float.class, new NumberStyleFormatter());
binder.setConversionService(conversionService);
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.add("myFloat", "1x2");