1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package com.opencsv.bean;
17
18 import com.opencsv.ICSVParser;
19 import com.opencsv.exceptions.CsvDataTypeMismatchException;
20 import org.apache.commons.lang3.StringUtils;
21
22 import javax.xml.datatype.DatatypeConfigurationException;
23 import javax.xml.datatype.DatatypeFactory;
24 import javax.xml.datatype.XMLGregorianCalendar;
25 import java.lang.reflect.Field;
26 import java.lang.reflect.InvocationTargetException;
27 import java.text.ParseException;
28 import java.text.SimpleDateFormat;
29 import java.util.*;
30
31
32
33
34
35
36
37
38
39
40
41
42 public class BeanFieldDate<T> extends AbstractBeanField<T> {
43
44 private final String formatString;
45 private final String locale;
46
47
48
49
50
51
52
53
54
55
56
57 public BeanFieldDate(Field field, boolean required, String formatString, String locale, Locale errorLocale) {
58 super(field, required, errorLocale);
59 this.formatString = formatString;
60 this.locale = locale;
61 }
62
63
64
65
66
67 private SimpleDateFormat getFormat() {
68 SimpleDateFormat sdf;
69 if (StringUtils.isNotEmpty(locale)) {
70 Locale l = Locale.forLanguageTag(locale);
71 sdf = new SimpleDateFormat(formatString, l);
72 } else {
73 sdf = new SimpleDateFormat(formatString);
74 }
75 return sdf;
76 }
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96 private <U> U convertDate(Object value, Class<U> fieldType)
97 throws CsvDataTypeMismatchException {
98 U o;
99
100 if(value instanceof String) {
101 Date d;
102 try {
103 d = getFormat().parse((String)value);
104 o = fieldType.getConstructor(Long.TYPE).newInstance(d.getTime());
105 }
106
107
108
109
110
111 catch(ParseException | InstantiationException
112 | IllegalAccessException | NoSuchMethodException
113 | InvocationTargetException e) {
114 CsvDataTypeMismatchException csve = new CsvDataTypeMismatchException(value, fieldType);
115 csve.initCause(e);
116 throw csve;
117 }
118 }
119 else if(Date.class.isAssignableFrom(value.getClass())) {
120 o = fieldType.cast(getFormat().format((Date)value));
121 }
122 else {
123 throw new CsvDataTypeMismatchException(value, fieldType,
124 ResourceBundle.getBundle(ICSVParser.DEFAULT_BUNDLE_NAME, errorLocale).getString("csvdate.not.date"));
125 }
126
127 return o;
128 }
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149 private <U> U convertCalendar(Object value, Class<U> fieldType)
150 throws CsvDataTypeMismatchException {
151 U o;
152
153 if(value instanceof String) {
154
155 Date d;
156 try {
157 d = getFormat().parse((String)value);
158 } catch (ParseException e) {
159 CsvDataTypeMismatchException csve = new CsvDataTypeMismatchException(value, fieldType);
160 csve.initCause(e);
161 throw csve;
162 }
163
164
165
166 GregorianCalendar gc = new GregorianCalendar();
167 gc.setTime(d);
168
169
170 if (fieldType == XMLGregorianCalendar.class) {
171 try {
172 o = fieldType.cast(DatatypeFactory
173 .newInstance()
174 .newXMLGregorianCalendar(gc));
175 } catch (DatatypeConfigurationException e) {
176
177
178
179 CsvDataTypeMismatchException ex = new CsvDataTypeMismatchException(
180 ResourceBundle.getBundle(ICSVParser.DEFAULT_BUNDLE_NAME, errorLocale).getString("xmlgregoriancalendar.impossible"));
181 ex.initCause(e);
182 throw ex;
183 }
184 }
185 else {
186 o = fieldType.cast(gc);
187 }
188 }
189 else {
190 Calendar c;
191 if(value instanceof XMLGregorianCalendar) {
192 c = ((XMLGregorianCalendar)value).toGregorianCalendar();
193 }
194 else if (value instanceof Calendar) {
195 c = (Calendar)value;
196 }
197 else {
198 throw new CsvDataTypeMismatchException(value, fieldType,
199 ResourceBundle.getBundle(ICSVParser.DEFAULT_BUNDLE_NAME, errorLocale).getString("csvdate.not.date"));
200 }
201 o = fieldType.cast(getFormat().format(c.getTime()));
202 }
203
204 return o;
205 }
206
207
208
209
210
211
212
213
214
215
216
217
218 private <U> U convertCommon(Object value, Class<U> fieldType)
219 throws CsvDataTypeMismatchException {
220 U o;
221 Class conversionClass = (fieldType == String.class)?value.getClass():fieldType;
222
223
224 if (Date.class.isAssignableFrom(conversionClass)) {
225 o = convertDate(value, fieldType);
226 } else if (Calendar.class.isAssignableFrom(conversionClass)
227 || XMLGregorianCalendar.class.isAssignableFrom(conversionClass)) {
228 o = convertCalendar(value, fieldType);
229 } else {
230 throw new CsvDataTypeMismatchException(value, fieldType,
231 ResourceBundle.getBundle(ICSVParser.DEFAULT_BUNDLE_NAME, errorLocale).getString("csvdate.not.date"));
232 }
233
234 return o;
235 }
236
237 @Override
238 protected Object convert(String value) throws CsvDataTypeMismatchException {
239 return StringUtils.isBlank(value) ? null : convertCommon(value, field.getType());
240 }
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255 @Override
256 protected String convertToWrite(Object value)
257 throws CsvDataTypeMismatchException {
258 return value == null ? null : convertCommon(value, String.class);
259 }
260 }