From 48b9e9a2034d9bcaa3b5c2bd62c827f1fae6be7b Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 30 Oct 2013 16:50:21 +0100 Subject: [PATCH] Spring uses Joda-Time 2.0's specific parseLocalDate/parseLocalTime/parseLocalDateTime methods now Issue: SPR-11014 --- build.gradle | 2 +- ...eTimeFormatAnnotationFormatterFactory.java | 18 +++++-- .../joda/JodaTimeFormatterRegistrar.java | 8 +-- .../format/datetime/joda/LocalDateParser.java | 52 +++++++++++++++++++ .../datetime/joda/LocalDateTimeParser.java | 52 +++++++++++++++++++ .../format/datetime/joda/LocalTimeParser.java | 52 +++++++++++++++++++ .../joda/JodaTimeFormattingTests.java | 37 +++---------- 7 files changed, 184 insertions(+), 37 deletions(-) create mode 100644 spring-context/src/main/java/org/springframework/format/datetime/joda/LocalDateParser.java create mode 100644 spring-context/src/main/java/org/springframework/format/datetime/joda/LocalDateTimeParser.java create mode 100644 spring-context/src/main/java/org/springframework/format/datetime/joda/LocalTimeParser.java diff --git a/build.gradle b/build.gradle index b56c62228c..e1aab17510 100644 --- a/build.gradle +++ b/build.gradle @@ -355,10 +355,10 @@ project("spring-context") { optional("javax.enterprise.concurrent:javax.enterprise.concurrent-api:1.0") optional("org.apache.geronimo.specs:geronimo-jms_1.1_spec:1.1") optional("org.eclipse.persistence:javax.persistence:2.0.0") + optional("joda-time:joda-time:2.2") optional("org.beanshell:bsh:2.0b4") optional("org.codehaus.groovy:groovy-all:${groovyVersion}") optional("org.jruby:jruby:1.7.2") - optional("joda-time:joda-time:2.2") optional("org.slf4j:slf4j-api:${slf4jVersion}") optional("javax.validation:validation-api:1.0.0.GA") optional("org.hibernate:hibernate-validator:4.3.0.Final") diff --git a/spring-context/src/main/java/org/springframework/format/datetime/joda/JodaDateTimeFormatAnnotationFormatterFactory.java b/spring-context/src/main/java/org/springframework/format/datetime/joda/JodaDateTimeFormatAnnotationFormatterFactory.java index 5239fc04e9..de14a7fb2b 100644 --- a/spring-context/src/main/java/org/springframework/format/datetime/joda/JodaDateTimeFormatAnnotationFormatterFactory.java +++ b/spring-context/src/main/java/org/springframework/format/datetime/joda/JodaDateTimeFormatAnnotationFormatterFactory.java @@ -22,7 +22,6 @@ import java.util.Date; import java.util.HashSet; import java.util.Set; -import org.joda.time.DateTime; import org.joda.time.LocalDate; import org.joda.time.LocalDateTime; import org.joda.time.LocalTime; @@ -40,6 +39,8 @@ import org.springframework.util.StringValueResolver; /** * Formats fields annotated with the {@link DateTimeFormat} annotation using Joda-Time. * + *

NOTE: Spring's Joda-Time support requires Joda-Time 2.x, as of Spring 4.0. + * * @author Keith Donald * @author Juergen Hoeller * @since 3.0 @@ -103,8 +104,19 @@ public class JodaDateTimeFormatAnnotationFormatterFactory } @Override - public Parser getParser(DateTimeFormat annotation, Class fieldType) { - return new DateTimeParser(getFormatter(annotation, fieldType)); + public Parser getParser(DateTimeFormat annotation, Class fieldType) { + if (LocalDate.class.equals(fieldType)) { + return new LocalDateParser(getFormatter(annotation, fieldType)); + } + else if (LocalTime.class.equals(fieldType)) { + return new LocalTimeParser(getFormatter(annotation, fieldType)); + } + else if (LocalDateTime.class.equals(fieldType)) { + return new LocalDateTimeParser(getFormatter(annotation, fieldType)); + } + else { + return new DateTimeParser(getFormatter(annotation, fieldType)); + } } /** diff --git a/spring-context/src/main/java/org/springframework/format/datetime/joda/JodaTimeFormatterRegistrar.java b/spring-context/src/main/java/org/springframework/format/datetime/joda/JodaTimeFormatterRegistrar.java index afb7769f4d..04e45fe316 100644 --- a/spring-context/src/main/java/org/springframework/format/datetime/joda/JodaTimeFormatterRegistrar.java +++ b/spring-context/src/main/java/org/springframework/format/datetime/joda/JodaTimeFormatterRegistrar.java @@ -38,6 +38,8 @@ import org.springframework.format.annotation.DateTimeFormat.ISO; /** * Configures Joda-Time's formatting system for use with Spring. * + *

NOTE: Spring's Joda-Time support requires Joda-Time 2.x, as of Spring 4.0. + * * @author Keith Donald * @author Juergen Hoeller * @author Phillip Webb @@ -165,17 +167,17 @@ public class JodaTimeFormatterRegistrar implements FormatterRegistrar { addFormatterForFields(registry, new ReadablePartialPrinter(dateFormatter), - new DateTimeParser(dateFormatter), + new LocalDateParser(dateFormatter), LocalDate.class); addFormatterForFields(registry, new ReadablePartialPrinter(timeFormatter), - new DateTimeParser(timeFormatter), + new LocalTimeParser(timeFormatter), LocalTime.class); addFormatterForFields(registry, new ReadablePartialPrinter(dateTimeFormatter), - new DateTimeParser(dateTimeFormatter), + new LocalDateTimeParser(dateTimeFormatter), LocalDateTime.class); addFormatterForFields(registry, diff --git a/spring-context/src/main/java/org/springframework/format/datetime/joda/LocalDateParser.java b/spring-context/src/main/java/org/springframework/format/datetime/joda/LocalDateParser.java new file mode 100644 index 0000000000..d197ccf06e --- /dev/null +++ b/spring-context/src/main/java/org/springframework/format/datetime/joda/LocalDateParser.java @@ -0,0 +1,52 @@ +/* + * Copyright 2002-2013 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.datetime.joda; + +import java.text.ParseException; +import java.util.Locale; + +import org.joda.time.LocalDate; +import org.joda.time.format.DateTimeFormatter; + +import org.springframework.format.Parser; + +/** + * Parses Joda {@link org.joda.time.LocalDate} instances using a {@link org.joda.time.format.DateTimeFormatter}. + * + * @author Juergen Hoeller + * @since 4.0 + */ +public final class LocalDateParser implements Parser { + + private final DateTimeFormatter formatter; + + + /** + * Create a new DateTimeParser. + * @param formatter the Joda DateTimeFormatter instance + */ + public LocalDateParser(DateTimeFormatter formatter) { + this.formatter = formatter; + } + + + @Override + public LocalDate parse(String text, Locale locale) throws ParseException { + return JodaTimeContextHolder.getFormatter(this.formatter, locale).parseLocalDate(text); + } + +} diff --git a/spring-context/src/main/java/org/springframework/format/datetime/joda/LocalDateTimeParser.java b/spring-context/src/main/java/org/springframework/format/datetime/joda/LocalDateTimeParser.java new file mode 100644 index 0000000000..5867f63828 --- /dev/null +++ b/spring-context/src/main/java/org/springframework/format/datetime/joda/LocalDateTimeParser.java @@ -0,0 +1,52 @@ +/* + * Copyright 2002-2013 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.datetime.joda; + +import java.text.ParseException; +import java.util.Locale; + +import org.joda.time.LocalDateTime; +import org.joda.time.format.DateTimeFormatter; + +import org.springframework.format.Parser; + +/** + * Parses Joda {@link org.joda.time.LocalDateTime} instances using a {@link org.joda.time.format.DateTimeFormatter}. + * + * @author Juergen Hoeller + * @since 4.0 + */ +public final class LocalDateTimeParser implements Parser { + + private final DateTimeFormatter formatter; + + + /** + * Create a new DateTimeParser. + * @param formatter the Joda DateTimeFormatter instance + */ + public LocalDateTimeParser(DateTimeFormatter formatter) { + this.formatter = formatter; + } + + + @Override + public LocalDateTime parse(String text, Locale locale) throws ParseException { + return JodaTimeContextHolder.getFormatter(this.formatter, locale).parseLocalDateTime(text); + } + +} diff --git a/spring-context/src/main/java/org/springframework/format/datetime/joda/LocalTimeParser.java b/spring-context/src/main/java/org/springframework/format/datetime/joda/LocalTimeParser.java new file mode 100644 index 0000000000..d7c86cb62e --- /dev/null +++ b/spring-context/src/main/java/org/springframework/format/datetime/joda/LocalTimeParser.java @@ -0,0 +1,52 @@ +/* + * Copyright 2002-2013 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.datetime.joda; + +import java.text.ParseException; +import java.util.Locale; + +import org.joda.time.LocalTime; +import org.joda.time.format.DateTimeFormatter; + +import org.springframework.format.Parser; + +/** + * Parses Joda {@link org.joda.time.LocalTime} instances using a {@link org.joda.time.format.DateTimeFormatter}. + * + * @author Juergen Hoeller + * @since 4.0 + */ +public final class LocalTimeParser implements Parser { + + private final DateTimeFormatter formatter; + + + /** + * Create a new DateTimeParser. + * @param formatter the Joda DateTimeFormatter instance + */ + public LocalTimeParser(DateTimeFormatter formatter) { + this.formatter = formatter; + } + + + @Override + public LocalTime parse(String text, Locale locale) throws ParseException { + return JodaTimeContextHolder.getFormatter(this.formatter, locale).parseLocalTime(text); + } + +} diff --git a/spring-context/src/test/java/org/springframework/format/datetime/joda/JodaTimeFormattingTests.java b/spring-context/src/test/java/org/springframework/format/datetime/joda/JodaTimeFormattingTests.java index f5a92d5c59..6cfbd538e4 100644 --- a/spring-context/src/test/java/org/springframework/format/datetime/joda/JodaTimeFormattingTests.java +++ b/spring-context/src/test/java/org/springframework/format/datetime/joda/JodaTimeFormattingTests.java @@ -16,11 +16,6 @@ package org.springframework.format.datetime.joda; -import static org.hamcrest.Matchers.equalTo; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; - import java.util.ArrayList; import java.util.Calendar; import java.util.Date; @@ -37,6 +32,7 @@ import org.joda.time.MutableDateTime; 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.core.convert.TypeDescriptor; @@ -46,6 +42,9 @@ import org.springframework.format.annotation.DateTimeFormat.ISO; import org.springframework.format.support.FormattingConversionService; import org.springframework.validation.DataBinder; +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; + /** * @author Keith Donald * @author Juergen Hoeller @@ -236,21 +235,10 @@ public class JodaTimeFormattingTests { @Test public void testBindLocalDateTimeAnnotated() { MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("localDateTimeAnnotated", "Saturday, October 31, 2009 12:00:00 PM "); + propertyValues.add("localDateTimeAnnotated", "Oct 31, 2009 12:00 PM"); binder.bind(propertyValues); assertEquals(0, binder.getBindingResult().getErrorCount()); - assertEquals("Saturday, October 31, 2009 12:00:00 PM ", binder.getBindingResult().getFieldValue( - "localDateTimeAnnotated")); - } - - @Test - public void testBindLocalDateTimeAnnotatedLong() { - MutablePropertyValues propertyValues = new MutablePropertyValues(); - propertyValues.add("localDateTimeAnnotatedLong", "October 31, 2009 12:00:00 PM "); - binder.bind(propertyValues); - assertEquals(0, binder.getBindingResult().getErrorCount()); - assertEquals("October 31, 2009 12:00:00 PM ", binder.getBindingResult().getFieldValue( - "localDateTimeAnnotatedLong")); + assertEquals("Oct 31, 2009 12:00 PM", binder.getBindingResult().getFieldValue("localDateTimeAnnotated")); } @Test @@ -510,12 +498,9 @@ public class JodaTimeFormattingTests { private LocalDateTime localDateTime; - @DateTimeFormat(style="FF") + @DateTimeFormat(style="MS") private LocalDateTime localDateTimeAnnotated; - @DateTimeFormat(style="LL") - private LocalDateTime localDateTimeAnnotatedLong; - private DateTime dateTime; @DateTimeFormat(style="MS") @@ -612,14 +597,6 @@ public class JodaTimeFormattingTests { this.localDateTimeAnnotated = localDateTimeAnnotated; } - public LocalDateTime getLocalDateTimeAnnotatedLong() { - return localDateTimeAnnotatedLong; - } - - public void setLocalDateTimeAnnotatedLong(LocalDateTime localDateTimeAnnotatedLong) { - this.localDateTimeAnnotatedLong = localDateTimeAnnotatedLong; - } - public DateTime getDateTime() { return dateTime; }