ui.format system refining from RC1 feedback: Support for one format annotation applying to multiple field types, Printer/Parser building blocks for more flexibility, full Joda time formatting support, FormattingService as a service entry-point for clients to use
This commit is contained in:
@@ -11,6 +11,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.MutableDateTime;
|
||||
import org.joda.time.format.ISODateTimeFormat;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
@@ -317,6 +318,35 @@ public class MappingTests {
|
||||
.getActivationDateTime());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiFieldToFieldMappingWithAssembler() {
|
||||
Mapper<Map, Account> mapper = MapperFactory.mapperBuilder(Map.class, Account.class)
|
||||
.setAutoMappingEnabled(false)
|
||||
// field to multiple fields
|
||||
.addAssemblerMapping("activationDateTime", new Converter<Map<String, String>, DateTime>() {
|
||||
public DateTime convert(Map<String, String> source) {
|
||||
MutableDateTime dateTime = new MutableDateTime();
|
||||
dateTime.setYear(Integer.parseInt(source.get("year")));
|
||||
dateTime.setMonthOfYear(Integer.parseInt(source.get("month")));
|
||||
dateTime.setDayOfMonth(Integer.parseInt(source.get("day")));
|
||||
dateTime.setHourOfDay(Integer.parseInt(source.get("hour")));
|
||||
dateTime.setMinuteOfHour(Integer.parseInt(source.get("minute")));
|
||||
dateTime.setSecondOfMinute(0);
|
||||
dateTime.setMillisOfSecond(0);
|
||||
return dateTime.toDateTime();
|
||||
}
|
||||
}).getMapper();
|
||||
Map<String, Object> source = new HashMap<String, Object>();
|
||||
source.put("activationDateTime.year", "2009");
|
||||
source.put("activationDateTime.month", "10");
|
||||
source.put("activationDateTime.day", "12");
|
||||
source.put("activationDateTime.hour", "12");
|
||||
source.put("activationDateTime.minute", "0");
|
||||
Account account = mapper.map(source, new Account());
|
||||
assertEquals(ISODateTimeFormat.dateTime().parseDateTime("2009-10-12T12:00:00.000-04:00"), account
|
||||
.getActivationDateTime());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void conditionalMapping() {
|
||||
Map<String, String> domestic = new HashMap<String, String>();
|
||||
@@ -328,17 +358,16 @@ public class MappingTests {
|
||||
domestic.put("cityCode", "whatever");
|
||||
|
||||
Mapper<Map, PhoneNumber> mapper = MapperFactory.mapperBuilder(Map.class, PhoneNumber.class)
|
||||
.addConditionalMapping("countryCode", "international == 'true'")
|
||||
.addConditionalMapping("cityCode", "international == 'true'")
|
||||
.getMapper();
|
||||
|
||||
.addConditionalMapping("countryCode", "international == 'true'").addConditionalMapping("cityCode",
|
||||
"international == 'true'").getMapper();
|
||||
|
||||
PhoneNumber number = mapper.map(domestic, new PhoneNumber());
|
||||
assertEquals("205", number.getAreaCode());
|
||||
assertEquals("339", number.getPrefix());
|
||||
assertEquals("1234", number.getLine());
|
||||
assertNull(number.getCountryCode());
|
||||
assertNull(number.getCityCode());
|
||||
|
||||
|
||||
Map<String, String> international = new HashMap<String, String>();
|
||||
international.put("international", "true");
|
||||
international.put("areaCode", "205");
|
||||
@@ -346,7 +375,7 @@ public class MappingTests {
|
||||
international.put("line", "1234");
|
||||
international.put("countryCode", "1");
|
||||
international.put("cityCode", "2");
|
||||
|
||||
|
||||
PhoneNumber number2 = mapper.map(international, new PhoneNumber());
|
||||
|
||||
assertEquals("205", number2.getAreaCode());
|
||||
@@ -479,7 +508,7 @@ public class MappingTests {
|
||||
|
||||
MapperFactory.defaultMapper().map(source, target);
|
||||
assertEquals(1, target.getNumber());
|
||||
assertTrue(item != target.getLineItem());
|
||||
assertTrue(item == target.getLineItem());
|
||||
assertEquals(new BigDecimal("30.00"), target.getLineItem().getAmount());
|
||||
assertEquals(source, target.getLineItem().getOrder());
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public class DateFormatterTests {
|
||||
cal.set(Calendar.YEAR, 2009);
|
||||
cal.set(Calendar.MONTH, Calendar.JUNE);
|
||||
cal.set(Calendar.DAY_OF_MONTH, 1);
|
||||
assertEquals("2009-06-01", formatter.format(cal.getTime(), Locale.US));
|
||||
assertEquals("2009-06-01", formatter.print(cal.getTime(), Locale.US));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.ui.format.jodatime;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.format.DateTimeFormat;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class DateTimeFormatterTests {
|
||||
|
||||
private DateTimeFormatter formatter = new DateTimeFormatter("yyyy-MM-dd");
|
||||
|
||||
@Test
|
||||
public void formatValue() {
|
||||
DateTime dateTime = DateTimeFormat.forPattern("yyyy-MM-dd").parseDateTime("2009-06-01");
|
||||
assertEquals("2009-06-01", formatter.format(dateTime, Locale.US));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseValue() throws ParseException {
|
||||
DateTime dateTime = DateTimeFormat.forPattern("yyyy-MM-dd").parseDateTime("2009-06-01");
|
||||
assertEquals(dateTime, formatter.parse("2009-06-01", Locale.US));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,12 +16,13 @@
|
||||
|
||||
package org.springframework.ui.format.number;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.text.ParseException;
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
@@ -33,7 +34,7 @@ public class CurrencyFormatterTests {
|
||||
|
||||
@Test
|
||||
public void formatValue() {
|
||||
assertEquals("$23.00", formatter.format(new BigDecimal("23"), Locale.US));
|
||||
assertEquals("$23.00", formatter.print(new BigDecimal("23"), Locale.US));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -41,11 +42,6 @@ public class CurrencyFormatterTests {
|
||||
assertEquals(new BigDecimal("23.56"), formatter.parse("$23.56", Locale.US));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseEmptyValue() throws ParseException {
|
||||
assertEquals(null, formatter.parse("", Locale.US));
|
||||
}
|
||||
|
||||
@Test(expected = ParseException.class)
|
||||
public void parseBogusValue() throws ParseException {
|
||||
formatter.parse("bogus", Locale.US);
|
||||
|
||||
@@ -34,7 +34,7 @@ public class DecimalFormatterTests {
|
||||
|
||||
@Test
|
||||
public void formatValue() {
|
||||
assertEquals("23.56", formatter.format(new BigDecimal("23.56"), Locale.US));
|
||||
assertEquals("23.56", formatter.print(new BigDecimal("23.56"), Locale.US));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -42,11 +42,6 @@ public class DecimalFormatterTests {
|
||||
assertEquals(new BigDecimal("23.56"), formatter.parse("23.56", Locale.US));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseEmptyValue() throws ParseException {
|
||||
assertEquals(null, formatter.parse("", Locale.US));
|
||||
}
|
||||
|
||||
@Test(expected = ParseException.class)
|
||||
public void parseBogusValue() throws ParseException {
|
||||
formatter.parse("bogus", Locale.US);
|
||||
|
||||
@@ -33,7 +33,7 @@ public class IntegerFormatterTests {
|
||||
|
||||
@Test
|
||||
public void formatValue() {
|
||||
assertEquals("23", formatter.format(23L, Locale.US));
|
||||
assertEquals("23", formatter.print(23L, Locale.US));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -41,11 +41,6 @@ public class IntegerFormatterTests {
|
||||
assertEquals((Long) 2356L, formatter.parse("2356", Locale.US));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseEmptyValue() throws ParseException {
|
||||
assertEquals(null, formatter.parse("", Locale.US));
|
||||
}
|
||||
|
||||
@Test(expected = ParseException.class)
|
||||
public void parseBogusValue() throws ParseException {
|
||||
formatter.parse("bogus", Locale.US);
|
||||
|
||||
@@ -34,7 +34,7 @@ public class PercentFormatterTests {
|
||||
|
||||
@Test
|
||||
public void formatValue() {
|
||||
assertEquals("23%", formatter.format(new BigDecimal(".23"), Locale.US));
|
||||
assertEquals("23%", formatter.print(new BigDecimal(".23"), Locale.US));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -43,11 +43,6 @@ public class PercentFormatterTests {
|
||||
Locale.US));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseEmptyValue() throws ParseException {
|
||||
assertEquals(null, formatter.parse("", Locale.US));
|
||||
}
|
||||
|
||||
@Test(expected = ParseException.class)
|
||||
public void parseBogusValue() throws ParseException {
|
||||
formatter.parse("bogus", Locale.US);
|
||||
|
||||
@@ -1,228 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.ui.format.support;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.text.ParseException;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.core.style.ToStringCreator;
|
||||
import org.springframework.ui.format.AnnotationFormatterFactory;
|
||||
import org.springframework.ui.format.Formatted;
|
||||
import org.springframework.ui.format.Formatter;
|
||||
import org.springframework.ui.format.number.CurrencyFormatter;
|
||||
import org.springframework.ui.format.number.IntegerFormatter;
|
||||
import org.springframework.ui.format.support.GenericFormatterRegistry;
|
||||
|
||||
/**
|
||||
* @author Keith Donald
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public class GenericFormatterRegistryTests {
|
||||
|
||||
private GenericFormatterRegistry registry;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
registry = new GenericFormatterRegistry();
|
||||
registry.setConversionService(new DefaultConversionService());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdd() throws ParseException {
|
||||
registry.addFormatterByType(new IntegerFormatter());
|
||||
Formatter formatter = registry.getFormatter(TypeDescriptor.valueOf(Integer.class));
|
||||
String formatted = formatter.format(new Integer(3), Locale.US);
|
||||
assertEquals("3", formatted);
|
||||
Integer i = (Integer) formatter.parse("3", Locale.US);
|
||||
assertEquals(new Integer(3), i);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddLookupByPrimitive() throws ParseException {
|
||||
registry.addFormatterByType(new IntegerFormatter());
|
||||
Formatter formatter = registry.getFormatter(TypeDescriptor.valueOf(int.class));
|
||||
String formatted = formatter.format(3, Locale.US);
|
||||
assertEquals("3", formatted);
|
||||
int integer = (Integer) formatter.parse("3", Locale.US);
|
||||
assertEquals(3, integer);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddByObjectType() {
|
||||
registry.addFormatterByType(BigInteger.class, new IntegerFormatter());
|
||||
Formatter formatter = registry.getFormatter(TypeDescriptor.valueOf(BigInteger.class));
|
||||
String formatted = formatter.format(new BigInteger("3"), Locale.US);
|
||||
assertEquals("3", formatted);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddByAnnotation() throws Exception {
|
||||
registry.addFormatterByAnnotation(Currency.class, new CurrencyFormatter());
|
||||
Formatter formatter = registry.getFormatter(new TypeDescriptor(getClass().getField("currencyField")));
|
||||
String formatted = formatter.format(new BigDecimal("5.00"), Locale.US);
|
||||
assertEquals("$5.00", formatted);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddAnnotationFormatterFactory() throws Exception {
|
||||
registry.addFormatterByAnnotation(new CurrencyAnnotationFormatterFactory());
|
||||
Formatter formatter = registry.getFormatter(new TypeDescriptor(getClass().getField("currencyField")));
|
||||
String formatted = formatter.format(new BigDecimal("5.00"), Locale.US);
|
||||
assertEquals("$5.00", formatted);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDefaultFormatterFromMetaAnnotation() throws Exception {
|
||||
Formatter formatter = registry.getFormatter(new TypeDescriptor(getClass().getField("smartCurrencyField")));
|
||||
String formatted = formatter.format(new BigDecimal("5.00"), Locale.US);
|
||||
assertEquals("$5.00", formatted);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDefaultFormatterForType() {
|
||||
Formatter formatter = registry.getFormatter(TypeDescriptor.valueOf(Address.class));
|
||||
Address address = new Address();
|
||||
address.street = "12345 Bel Aire Estates";
|
||||
address.city = "Palm Bay";
|
||||
address.state = "FL";
|
||||
address.zip = "12345";
|
||||
String formatted = formatter.format(address, Locale.US);
|
||||
assertEquals("12345 Bel Aire Estates:Palm Bay:FL:12345", formatted);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDefaultFormatterNull() throws ParseException {
|
||||
assertNull(registry.getFormatter(TypeDescriptor.valueOf(Integer.class)));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testGetFormatterCannotConvert() {
|
||||
registry.addFormatterByType(Integer.class, new AddressFormatter());
|
||||
}
|
||||
|
||||
@Currency
|
||||
public BigDecimal currencyField;
|
||||
|
||||
@SmartCurrency
|
||||
public BigDecimal smartCurrencyField;
|
||||
|
||||
@Target( { ElementType.METHOD, ElementType.FIELD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Currency {
|
||||
}
|
||||
|
||||
@Target( { ElementType.METHOD, ElementType.FIELD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Formatted(CurrencyFormatter.class)
|
||||
public @interface SmartCurrency {
|
||||
}
|
||||
|
||||
public static class CurrencyAnnotationFormatterFactory implements AnnotationFormatterFactory<Currency, Number> {
|
||||
|
||||
private final CurrencyFormatter currencyFormatter = new CurrencyFormatter();
|
||||
|
||||
public Formatter<Number> getFormatter(Currency annotation) {
|
||||
return this.currencyFormatter;
|
||||
}
|
||||
}
|
||||
|
||||
@Formatted(AddressFormatter.class)
|
||||
public static class Address {
|
||||
|
||||
private String street;
|
||||
private String city;
|
||||
private String state;
|
||||
private String zip;
|
||||
private String country;
|
||||
|
||||
public String getStreet() {
|
||||
return street;
|
||||
}
|
||||
|
||||
public void setStreet(String street) {
|
||||
this.street = street;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public String getZip() {
|
||||
return zip;
|
||||
}
|
||||
|
||||
public void setZip(String zip) {
|
||||
this.zip = zip;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setCountry(String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return new ToStringCreator(this).append("street", street).append("city", city).append("state", state)
|
||||
.append("zip", zip).toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static class AddressFormatter implements Formatter<Address> {
|
||||
|
||||
public String format(Address address, Locale locale) {
|
||||
return address.getStreet() + ":" + address.getCity() + ":" + address.getState() + ":" + address.getZip();
|
||||
}
|
||||
|
||||
public Address parse(String formatted, Locale locale) throws ParseException {
|
||||
Address address = new Address();
|
||||
String[] fields = formatted.split(":");
|
||||
address.setStreet(fields[0]);
|
||||
address.setCity(fields[1]);
|
||||
address.setState(fields[2]);
|
||||
address.setZip(fields[3]);
|
||||
return address;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.ui.format.support;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.format.DateTimeFormat;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.ui.format.jodatime.DateTimeFormatAnnotationFormatterFactory;
|
||||
import org.springframework.ui.format.jodatime.DateTimeParser;
|
||||
import org.springframework.ui.format.jodatime.ReadablePartialPrinter;
|
||||
import org.springframework.ui.format.jodatime.DateTimeFormat.FormatStyle;
|
||||
import org.springframework.ui.format.number.IntegerFormatter;
|
||||
|
||||
/**
|
||||
* @author Keith Donald
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public class GenericFormattingServiceTests {
|
||||
|
||||
private GenericFormattingService formattingService;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
formattingService = new GenericFormattingService();
|
||||
formattingService.setParentConversionService(new DefaultConversionService());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFormatFieldForTypeWithFormatter() throws ParseException {
|
||||
formattingService.addFormatterForFieldType(Number.class, new IntegerFormatter());
|
||||
String formatted = formattingService.print(new Integer(3), TypeDescriptor.valueOf(Integer.class), Locale.US);
|
||||
assertEquals("3", formatted);
|
||||
Integer i = (Integer) formattingService.parse("3", TypeDescriptor.valueOf(Integer.class), Locale.US);
|
||||
assertEquals(new Integer(3), i);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFormatFieldForTypeWithPrinterParserWithCoersion() throws ParseException {
|
||||
formattingService.getConverterRegistry().addConverter(new Converter<DateTime, LocalDate>() {
|
||||
public LocalDate convert(DateTime source) {
|
||||
return source.toLocalDate();
|
||||
}
|
||||
});
|
||||
formattingService.addFormatterForFieldType(LocalDate.class, new ReadablePartialPrinter(DateTimeFormat
|
||||
.shortDate()), new DateTimeParser(DateTimeFormat.shortDate()));
|
||||
String formatted = formattingService.print(new LocalDate(2009, 10, 31), TypeDescriptor.valueOf(LocalDate.class), Locale.US);
|
||||
assertEquals("10/31/09", formatted);
|
||||
LocalDate date = (LocalDate) formattingService.parse("10/31/09", TypeDescriptor.valueOf(LocalDate.class), Locale.US);
|
||||
assertEquals(new LocalDate(2009, 10, 31), date);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFormatFieldForAnnotation() throws Exception {
|
||||
formattingService.getConverterRegistry().addConverter(new Converter<Date, Long>() {
|
||||
public Long convert(Date source) {
|
||||
return source.getTime();
|
||||
}
|
||||
});
|
||||
formattingService.getConverterRegistry().addConverter(new Converter<DateTime, Date>() {
|
||||
public Date convert(DateTime source) {
|
||||
return source.toDate();
|
||||
}
|
||||
});
|
||||
formattingService.addFormatterForFieldAnnotation(new DateTimeFormatAnnotationFormatterFactory());
|
||||
String formatted = formattingService.print(new LocalDate(2009, 10, 31).toDateTimeAtCurrentTime().toDate(), new TypeDescriptor(Model.class.getField("date")), Locale.US);
|
||||
assertEquals("10/31/09", formatted);
|
||||
LocalDate date = new LocalDate(formattingService.parse("10/31/09", new TypeDescriptor(Model.class.getField("date")), Locale.US));
|
||||
assertEquals(new LocalDate(2009, 10, 31), date);
|
||||
}
|
||||
|
||||
private static class Model {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@org.springframework.ui.format.jodatime.DateTimeFormat(dateStyle=FormatStyle.SHORT)
|
||||
public Date date;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
package org.springframework.ui.format.support;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.ui.format.support.MethodInvokingFormatter;
|
||||
|
||||
public class MethodInvokingFormatterTests {
|
||||
|
||||
private MethodInvokingFormatter formatter = new MethodInvokingFormatter(AccountNumber.class, "getFormatted",
|
||||
"valueOf");
|
||||
|
||||
private MethodInvokingFormatter formatter2 = new MethodInvokingFormatter(I8nAccountNumber.class, "getFormatted",
|
||||
"valueOf");
|
||||
|
||||
@Test
|
||||
public void testFormat() {
|
||||
assertEquals("123456789", formatter.format(new AccountNumber(123456789L), null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParse() {
|
||||
assertEquals(new Long(123456789), ((AccountNumber) formatter.parse("123456789", null)).number);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFormatI18n() {
|
||||
assertEquals("123456789", formatter2.format(new I8nAccountNumber(123456789L), Locale.GERMAN));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseI18n() {
|
||||
assertEquals(new Long(123456789), ((I8nAccountNumber) formatter2.parse("123456789", Locale.GERMAN)).number);
|
||||
}
|
||||
|
||||
public static class AccountNumber {
|
||||
|
||||
private Long number;
|
||||
|
||||
public AccountNumber(Long number) {
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
public String getFormatted() {
|
||||
return number.toString();
|
||||
}
|
||||
|
||||
public static AccountNumber valueOf(String str) {
|
||||
return new AccountNumber(Long.valueOf(str));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class I8nAccountNumber {
|
||||
|
||||
private Long number;
|
||||
|
||||
public I8nAccountNumber(Long number) {
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
public String getFormatted(Locale locale) {
|
||||
assertEquals(Locale.GERMAN, locale);
|
||||
return number.toString();
|
||||
}
|
||||
|
||||
public static I8nAccountNumber valueOf(String str, Locale locale) {
|
||||
assertEquals(Locale.GERMAN, locale);
|
||||
return new I8nAccountNumber(Long.valueOf(str));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -16,21 +16,20 @@
|
||||
|
||||
package org.springframework.validation;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
import java.beans.PropertyEditor;
|
||||
import java.beans.PropertyEditorSupport;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Target;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
@@ -45,12 +44,12 @@ import org.springframework.beans.SerializablePerson;
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.beans.propertyeditors.CustomCollectionEditor;
|
||||
import org.springframework.beans.propertyeditors.CustomNumberEditor;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.context.support.ResourceBundleMessageSource;
|
||||
import org.springframework.context.support.StaticMessageSource;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.ui.format.number.DecimalFormatter;
|
||||
import org.springframework.ui.format.Formatted;
|
||||
import org.springframework.ui.format.support.GenericFormatterRegistry;
|
||||
import org.springframework.ui.format.support.GenericFormattingService;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -304,7 +303,10 @@ public class DataBinderTests extends TestCase {
|
||||
public void testBindingWithFormatter() {
|
||||
TestBean tb = new TestBean();
|
||||
DataBinder binder = new DataBinder(tb);
|
||||
binder.getFormatterRegistry().addFormatterByType(Float.class, new DecimalFormatter());
|
||||
GenericFormattingService formattingService = new GenericFormattingService();
|
||||
formattingService.setParentConversionService(new DefaultConversionService());
|
||||
formattingService.addFormatterForFieldType(Float.class, new DecimalFormatter());
|
||||
binder.setFormattingService(formattingService);
|
||||
MutablePropertyValues pvs = new MutablePropertyValues();
|
||||
pvs.addPropertyValue("myFloat", "1,2");
|
||||
|
||||
@@ -329,46 +331,6 @@ public class DataBinderTests extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testBindingWithDefaultFormatterFromField() {
|
||||
doTestBindingWithDefaultFormatter(new FormattedFieldTestBean());
|
||||
}
|
||||
|
||||
public void testBindingWithDefaultFormatterFromGetter() {
|
||||
doTestBindingWithDefaultFormatter(new FormattedGetterTestBean());
|
||||
}
|
||||
|
||||
public void testBindingWithDefaultFormatterFromSetter() {
|
||||
doTestBindingWithDefaultFormatter(new FormattedSetterTestBean());
|
||||
}
|
||||
|
||||
private void doTestBindingWithDefaultFormatter(Object tb) {
|
||||
DataBinder binder = new DataBinder(tb);
|
||||
// force formatter registry to be created
|
||||
binder.getFormatterRegistry();
|
||||
MutablePropertyValues pvs = new MutablePropertyValues();
|
||||
pvs.addPropertyValue("number", "1,2");
|
||||
|
||||
LocaleContextHolder.setLocale(Locale.GERMAN);
|
||||
try {
|
||||
binder.bind(pvs);
|
||||
assertEquals(new Float("1.2"), binder.getBindingResult().getRawFieldValue("number"));
|
||||
assertEquals("1,2", binder.getBindingResult().getFieldValue("number"));
|
||||
|
||||
PropertyEditor editor = binder.getBindingResult().findEditor("number", Float.class);
|
||||
assertNotNull(editor);
|
||||
editor.setValue(new Float("1.4"));
|
||||
assertEquals("1,4", editor.getAsText());
|
||||
|
||||
editor = binder.getBindingResult().findEditor("number", null);
|
||||
assertNotNull(editor);
|
||||
editor.setAsText("1,6");
|
||||
assertEquals(new Float("1.6"), editor.getValue());
|
||||
}
|
||||
finally {
|
||||
LocaleContextHolder.resetLocaleContext();
|
||||
}
|
||||
}
|
||||
|
||||
public void testBindingWithAllowedFields() throws Exception {
|
||||
TestBean rod = new TestBean();
|
||||
DataBinder binder = new DataBinder(rod);
|
||||
@@ -1423,56 +1385,4 @@ public class DataBinderTests extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Target({ElementType.METHOD, ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Formatted(DecimalFormatter.class)
|
||||
public @interface Decimal {
|
||||
}
|
||||
|
||||
|
||||
private static class FormattedFieldTestBean {
|
||||
|
||||
@Decimal
|
||||
private Float number;
|
||||
|
||||
public Float getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public void setNumber(Float number) {
|
||||
this.number = number;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class FormattedGetterTestBean {
|
||||
|
||||
private Float number;
|
||||
|
||||
@Decimal
|
||||
public Float getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public void setNumber(Float number) {
|
||||
this.number = number;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class FormattedSetterTestBean {
|
||||
|
||||
private Float number;
|
||||
|
||||
public Float getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
@Decimal
|
||||
public void setNumber(Float number) {
|
||||
this.number = number;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user