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:
Keith Donald
2009-10-30 18:44:40 +00:00
parent 471fbf7ebf
commit 913bc03a3b
56 changed files with 1731 additions and 1609 deletions

View File

@@ -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());
}

View File

@@ -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

View File

@@ -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));
}
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}

View File

@@ -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));
}
}
}

View File

@@ -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;
}
}
}