34
34
import org .springframework .format .Parser ;
35
35
import org .springframework .format .Printer ;
36
36
import org .springframework .format .annotation .DateTimeFormat ;
37
- import org .springframework .format .annotation .DateTimeFormat .ISO ;
38
- import org .springframework .util .StringUtils ;
39
37
import org .springframework .util .StringValueResolver ;
40
38
41
39
/**
49
47
public class JodaDateTimeFormatAnnotationFormatterFactory
50
48
implements AnnotationFormatterFactory <DateTimeFormat >, EmbeddedValueResolverAware {
51
49
52
- private final Set <Class <?>> fieldTypes ;
53
-
54
- private StringValueResolver embeddedValueResolver ;
50
+ private static final Set <Class <?>> FIELD_TYPES ;
51
+ static {
52
+ // Create the set of field types that may be annotated with @DateTimeFormat.
53
+ // Note: the 3 ReadablePartial concrete types are registered explicitly since
54
+ // addFormatterForFieldType rules exist for each of these types
55
+ // (if we did not do this, the default byType rules for LocalDate, LocalTime,
56
+ // and LocalDateTime would take precedence over the annotation rule, which
57
+ // is not what we want)
58
+ Set <Class <?>> fieldTypes = new HashSet <Class <?>>(7 );
59
+ fieldTypes .add (ReadableInstant .class );
60
+ fieldTypes .add (LocalDate .class );
61
+ fieldTypes .add (LocalTime .class );
62
+ fieldTypes .add (LocalDateTime .class );
63
+ fieldTypes .add (Date .class );
64
+ fieldTypes .add (Calendar .class );
65
+ fieldTypes .add (Long .class );
66
+ FIELD_TYPES = Collections .unmodifiableSet (fieldTypes );
67
+ }
55
68
56
69
57
- public JodaDateTimeFormatAnnotationFormatterFactory () {
58
- this .fieldTypes = createFieldTypes ();
59
- }
70
+ private StringValueResolver embeddedValueResolver ;
60
71
61
72
62
73
public final Set <Class <?>> getFieldTypes () {
63
- return this . fieldTypes ;
74
+ return FIELD_TYPES ;
64
75
}
65
76
66
77
public void setEmbeddedValueResolver (StringValueResolver resolver ) {
@@ -72,77 +83,41 @@ protected String resolveEmbeddedValue(String value) {
72
83
}
73
84
74
85
public Printer <?> getPrinter (DateTimeFormat annotation , Class <?> fieldType ) {
75
- DateTimeFormatter formatter = configureDateTimeFormatterFrom (annotation );
86
+ DateTimeFormatter formatter = getFormatter (annotation , fieldType );
87
+
76
88
if (ReadableInstant .class .isAssignableFrom (fieldType )) {
77
89
return new ReadableInstantPrinter (formatter );
78
90
}
79
- else if (ReadablePartial .class .isAssignableFrom (fieldType )) {
91
+
92
+ if (ReadablePartial .class .isAssignableFrom (fieldType )) {
80
93
return new ReadablePartialPrinter (formatter );
81
94
}
82
- else if (Calendar .class .isAssignableFrom (fieldType )) {
95
+
96
+ if (Calendar .class .isAssignableFrom (fieldType )) {
83
97
// assumes Calendar->ReadableInstant converter is registered
84
98
return new ReadableInstantPrinter (formatter );
85
99
}
86
- else {
87
- // assumes Date->Long converter is registered
88
- return new MillisecondInstantPrinter (formatter );
89
- }
100
+
101
+ // assumes Date->Long converter is registered
102
+ return new MillisecondInstantPrinter (formatter );
90
103
}
91
104
92
105
public Parser <DateTime > getParser (DateTimeFormat annotation , Class <?> fieldType ) {
93
- return new DateTimeParser (configureDateTimeFormatterFrom (annotation ));
106
+ return new DateTimeParser (getFormatter (annotation , fieldType ));
94
107
}
95
108
96
- // internal helpers
97
-
98
109
/**
99
- * Create the set of field types that may be annotated with @DateTimeFormat.
100
- * Note: the 3 ReadablePartial concrete types are registered explicitly since addFormatterForFieldType rules exist for each of these types
101
- * (if we did not do this, the default byType rules for LocalDate, LocalTime, and LocalDateTime would take precedence over the annotation rule, which is not what we want)
102
- * @see JodaTimeFormatterRegistrar#registerFormatters(org.springframework.format.FormatterRegistry)
110
+ * Factory method used to create a {@link DateTimeFormatter}.
111
+ * @param annotation the format annotation for the field
112
+ * @param fieldType the type of field
113
+ * @return a {@link DateTimeFormatter} instance
114
+ * @since 3.2
103
115
*/
104
- private Set <Class <?>> createFieldTypes () {
105
- Set <Class <?>> rawFieldTypes = new HashSet <Class <?>>(7 );
106
- rawFieldTypes .add (ReadableInstant .class );
107
- rawFieldTypes .add (LocalDate .class );
108
- rawFieldTypes .add (LocalTime .class );
109
- rawFieldTypes .add (LocalDateTime .class );
110
- rawFieldTypes .add (Date .class );
111
- rawFieldTypes .add (Calendar .class );
112
- rawFieldTypes .add (Long .class );
113
- return Collections .unmodifiableSet (rawFieldTypes );
114
- }
115
-
116
- private DateTimeFormatter configureDateTimeFormatterFrom (DateTimeFormat annotation ) {
117
- if (StringUtils .hasLength (annotation .pattern ())) {
118
- return forPattern (resolveEmbeddedValue (annotation .pattern ()));
119
- }
120
- else if (annotation .iso () != ISO .NONE ) {
121
- return forIso (annotation .iso ());
122
- }
123
- else {
124
- return forStyle (resolveEmbeddedValue (annotation .style ()));
125
- }
126
- }
127
-
128
- private DateTimeFormatter forPattern (String pattern ) {
129
- return org .joda .time .format .DateTimeFormat .forPattern (pattern );
130
- }
131
-
132
- private DateTimeFormatter forStyle (String style ) {
133
- return org .joda .time .format .DateTimeFormat .forStyle (style );
116
+ protected DateTimeFormatter getFormatter (DateTimeFormat annotation , Class <?> fieldType ) {
117
+ DateTimeFormatterFactory factory = new DateTimeFormatterFactory ();
118
+ factory .setStyle (resolveEmbeddedValue (annotation .style ()));
119
+ factory .setIso (annotation .iso ());
120
+ factory .setPattern (resolveEmbeddedValue (annotation .pattern ()));
121
+ return factory .getDateTimeFormatter ();
134
122
}
135
-
136
- private DateTimeFormatter forIso (ISO iso ) {
137
- if (iso == ISO .DATE ) {
138
- return org .joda .time .format .ISODateTimeFormat .date ();
139
- }
140
- else if (iso == ISO .TIME ) {
141
- return org .joda .time .format .ISODateTimeFormat .time ();
142
- }
143
- else {
144
- return org .joda .time .format .ISODateTimeFormat .dateTime ();
145
- }
146
- }
147
-
148
123
}
0 commit comments