1 package com.github.mygreen.supercsv.builder.joda;
2
3 import java.util.Locale;
4 import java.util.Optional;
5 import java.util.TimeZone;
6
7 import org.joda.time.Chronology;
8 import org.joda.time.DateTimeZone;
9 import org.joda.time.ReadablePartial;
10 import org.joda.time.chrono.ISOChronology;
11 import org.joda.time.chrono.LenientChronology;
12 import org.joda.time.format.DateTimeFormat;
13 import org.joda.time.format.DateTimeFormatter;
14
15 import com.github.mygreen.supercsv.annotation.constraint.CsvDateTimeRange;
16 import com.github.mygreen.supercsv.annotation.constraint.CsvDateTimeMin;
17 import com.github.mygreen.supercsv.annotation.constraint.CsvDateTimeMax;
18 import com.github.mygreen.supercsv.annotation.format.CsvDateTimeFormat;
19 import com.github.mygreen.supercsv.builder.AbstractProcessorBuilder;
20 import com.github.mygreen.supercsv.builder.Configuration;
21 import com.github.mygreen.supercsv.builder.FieldAccessor;
22 import com.github.mygreen.supercsv.cellprocessor.constraint.DateTimeRangeFactory;
23 import com.github.mygreen.supercsv.cellprocessor.constraint.DateTimeMinFactory;
24 import com.github.mygreen.supercsv.cellprocessor.constraint.DateTimeMaxFactory;
25 import com.github.mygreen.supercsv.cellprocessor.format.JodaFormatWrapper;
26 import com.github.mygreen.supercsv.cellprocessor.format.TextFormatter;
27 import com.github.mygreen.supercsv.util.Utils;
28
29
30
31
32
33
34
35
36
37
38
39 public abstract class AbstractJodaProcessorBuilder<T> extends AbstractProcessorBuilder<T> {
40
41 public AbstractJodaProcessorBuilder() {
42 super();
43
44 }
45
46 @Override
47 protected void init() {
48 super.init();
49
50
51 registerForConstraint(CsvDateTimeRange.class, new DateTimeRangeFactory<>());
52 registerForConstraint(CsvDateTimeMin.class, new DateTimeMinFactory<>());
53 registerForConstraint(CsvDateTimeMax.class, new DateTimeMaxFactory<>());
54
55 }
56
57
58
59
60
61
62
63
64 protected DateTimeFormatter createFormatter(final FieldAccessor field, final Configuration config) {
65
66 final Optional<CsvDateTimeFormat> formatAnno = field.getAnnotation(CsvDateTimeFormat.class);
67 if(!formatAnno.isPresent()) {
68 return DateTimeFormat.forPattern(getDefaultPattern());
69 }
70
71 String pattern = formatAnno.get().pattern();
72 if(pattern.isEmpty()) {
73 pattern = getDefaultPattern();
74 }
75
76 final Locale locale = Utils.getLocale(formatAnno.get().locale());
77 final DateTimeZone zone = formatAnno.get().timezone().isEmpty() ? DateTimeZone.getDefault()
78 : DateTimeZone.forTimeZone(TimeZone.getTimeZone(formatAnno.get().timezone()));
79
80 final DateTimeFormatter formatter = DateTimeFormat.forPattern(pattern)
81 .withLocale(locale)
82 .withZone(zone);
83
84 final boolean lenient = formatAnno.get().lenient();
85 if(lenient) {
86 Chronology chronology = LenientChronology.getInstance(ISOChronology.getInstance());
87 return formatter.withChronology(chronology);
88
89 } else {
90 return formatter;
91 }
92
93 }
94
95 @SuppressWarnings("unchecked")
96 @Override
97 protected TextFormatter<T> getDefaultFormatter(final FieldAccessor field, final Configuration config) {
98
99 final Optional<CsvDateTimeFormat> formatAnno = field.getAnnotation(CsvDateTimeFormat.class);
100 final String pattern = getPattern(field);
101 final DateTimeFormatter formatter = createFormatter(field, config);
102
103 final JodaFormatWrapper<T> wrapper = new JodaFormatWrapper<>(formatter, (Class<T>)field.getType());
104 wrapper.setPattern(pattern);
105 formatAnno.ifPresent(a -> wrapper.setValidationMessage(a.message()));
106 return wrapper;
107 }
108
109
110
111
112
113
114
115
116
117 protected String getPattern(final FieldAccessor field) {
118 return field.getAnnotation(CsvDateTimeFormat.class)
119 .map(a -> a.pattern())
120 .filter(p -> !p.isEmpty())
121 .orElse(getDefaultPattern());
122 }
123
124
125
126
127
128
129 protected abstract String getDefaultPattern();
130
131 }