1 package com.github.mygreen.supercsv.builder;
2
3 import java.lang.annotation.Annotation;
4 import java.util.ArrayList;
5 import java.util.Collections;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.Optional;
9 import java.util.Set;
10
11 import org.supercsv.cellprocessor.ift.CellProcessor;
12
13 import com.github.mygreen.supercsv.annotation.constraint.CsvEquals;
14 import com.github.mygreen.supercsv.annotation.constraint.CsvRequire;
15 import com.github.mygreen.supercsv.annotation.constraint.CsvUnique;
16 import com.github.mygreen.supercsv.annotation.constraint.CsvUniqueHashCode;
17 import com.github.mygreen.supercsv.annotation.conversion.CsvDefaultValue;
18 import com.github.mygreen.supercsv.annotation.conversion.CsvFullChar;
19 import com.github.mygreen.supercsv.annotation.conversion.CsvHalfChar;
20 import com.github.mygreen.supercsv.annotation.conversion.CsvLeftPad;
21 import com.github.mygreen.supercsv.annotation.conversion.CsvLower;
22 import com.github.mygreen.supercsv.annotation.conversion.CsvMultiPad;
23 import com.github.mygreen.supercsv.annotation.conversion.CsvNullConvert;
24 import com.github.mygreen.supercsv.annotation.conversion.CsvOneSideTrim;
25 import com.github.mygreen.supercsv.annotation.conversion.CsvRegexReplace;
26 import com.github.mygreen.supercsv.annotation.conversion.CsvRightPad;
27 import com.github.mygreen.supercsv.annotation.conversion.CsvTrim;
28 import com.github.mygreen.supercsv.annotation.conversion.CsvUpper;
29 import com.github.mygreen.supercsv.annotation.conversion.CsvWordReplace;
30 import com.github.mygreen.supercsv.annotation.format.CsvFormat;
31 import com.github.mygreen.supercsv.cellprocessor.ConstraintProcessorFactory;
32 import com.github.mygreen.supercsv.cellprocessor.ConstraintProcessorHandler;
33 import com.github.mygreen.supercsv.cellprocessor.ConversionProcessorFactory;
34 import com.github.mygreen.supercsv.cellprocessor.ConversionProcessorHandler;
35 import com.github.mygreen.supercsv.cellprocessor.ProcessorFactory;
36 import com.github.mygreen.supercsv.cellprocessor.constraint.EqualsFactory;
37 import com.github.mygreen.supercsv.cellprocessor.constraint.RequireFactory;
38 import com.github.mygreen.supercsv.cellprocessor.constraint.UniqueFactory;
39 import com.github.mygreen.supercsv.cellprocessor.constraint.UniqueHashCodeFactory;
40 import com.github.mygreen.supercsv.cellprocessor.conversion.DefaultValueFactory;
41 import com.github.mygreen.supercsv.cellprocessor.conversion.FullCharFactory;
42 import com.github.mygreen.supercsv.cellprocessor.conversion.HalfCharFactory;
43 import com.github.mygreen.supercsv.cellprocessor.conversion.LeftPadFactory;
44 import com.github.mygreen.supercsv.cellprocessor.conversion.LowerFactory;
45 import com.github.mygreen.supercsv.cellprocessor.conversion.MultiPadFactory;
46 import com.github.mygreen.supercsv.cellprocessor.conversion.NullConvertFactory;
47 import com.github.mygreen.supercsv.cellprocessor.conversion.OneSideTrimFactory;
48 import com.github.mygreen.supercsv.cellprocessor.conversion.RegexReplaceFactory;
49 import com.github.mygreen.supercsv.cellprocessor.conversion.RightPadFactory;
50 import com.github.mygreen.supercsv.cellprocessor.conversion.TrimFactory;
51 import com.github.mygreen.supercsv.cellprocessor.conversion.UpperFactory;
52 import com.github.mygreen.supercsv.cellprocessor.conversion.WordReplaceFactory;
53 import com.github.mygreen.supercsv.cellprocessor.format.ParseProcessorFactory;
54 import com.github.mygreen.supercsv.cellprocessor.format.PrintProcessorFactory;
55 import com.github.mygreen.supercsv.cellprocessor.format.TextFormatter;
56
57
58
59
60
61
62
63
64
65
66 public abstract class AbstractProcessorBuilder<T> implements ProcessorBuilder<T> {
67
68
69
70
71 protected List<ProcessorFactory> readingFactory = new ArrayList<>();
72
73
74
75
76 protected List<ProcessorFactory> writingFactory = new ArrayList<>();
77
78
79
80
81 protected ConversionProcessorHandleressorHandler.html#ConversionProcessorHandler">ConversionProcessorHandler conversionHandler = new ConversionProcessorHandler();
82
83
84
85
86 protected ConstraintProcessorHandleressorHandler.html#ConstraintProcessorHandler">ConstraintProcessorHandler constraintHandler = new ConstraintProcessorHandler();
87
88
89
90
91
92 public AbstractProcessorBuilder() {
93 init();
94 }
95
96
97
98
99
100 protected void init() {
101
102
103 registerForReading(conversionHandler);
104 registerForReading(new ParseProcessorFactory<>());
105 registerForReading(constraintHandler);
106
107
108 registerForWriting(constraintHandler);
109 registerForWriting(new PrintProcessorFactory<>());
110 registerForWriting(conversionHandler);
111
112
113 registerForConversion(CsvNullConvert.class, new NullConvertFactory());
114 registerForConversion(CsvDefaultValue.class, new DefaultValueFactory());
115 registerForConversion(CsvTrim.class, new TrimFactory());
116 registerForConversion(CsvUpper.class, new UpperFactory());
117 registerForConversion(CsvLower.class, new LowerFactory());
118 registerForConversion(CsvRegexReplace.class, new RegexReplaceFactory());
119 registerForConversion(CsvWordReplace.class, new WordReplaceFactory());
120 registerForConversion(CsvFullChar.class, new FullCharFactory());
121 registerForConversion(CsvHalfChar.class, new HalfCharFactory());
122 registerForConversion(CsvLeftPad.class, new LeftPadFactory());
123 registerForConversion(CsvRightPad.class, new RightPadFactory());
124 registerForConversion(CsvMultiPad.class, new MultiPadFactory());
125 registerForConversion(CsvOneSideTrim.class, new OneSideTrimFactory());
126
127
128 registerForConstraint(CsvRequire.class, new RequireFactory());
129 registerForConstraint(CsvUnique.class, new UniqueFactory<>());
130 registerForConstraint(CsvUniqueHashCode.class, new UniqueHashCodeFactory<>());
131 registerForConstraint(CsvEquals.class, new EqualsFactory<>());
132
133 }
134
135 @Override
136 public Optional<CellProcessor> buildForReading(final Class<T> type, final FieldAccessor field,
137 final Configuration config, final Class<?>[] groups) {
138
139
140 final List<ProcessorFactory> factories = new ArrayList<>(readingFactory);
141 Collections.reverse(factories);
142
143 final TextFormatter<T> formatter = getFormatter(field, config);
144
145 Optional<CellProcessor> processor = Optional.empty();
146 for(ProcessorFactory factory : factories) {
147 processor = factory.create(processor, field, formatter, config, BuildCase.Read, groups);
148 }
149
150 return processor;
151
152 }
153
154 @Override
155 public Optional<CellProcessor> buildForWriting(final Class<T> type, final FieldAccessor field,
156 final Configuration config, final Class<?>[] groups) {
157
158
159 final List<ProcessorFactory> factories = new ArrayList<>(writingFactory);
160 Collections.reverse(factories);
161
162 final TextFormatter<T> formatter = getFormatter(field, config);
163
164 Optional<CellProcessor> processor = Optional.empty();
165 for(ProcessorFactory factory : factories) {
166
167
168 if(config.isSkipValidationOnWrite()
169 && factory instanceof ConstraintProcessorHandler) {
170 continue;
171 }
172
173 processor = factory.create(processor, field, formatter, config, BuildCase.Write, groups);
174 }
175
176 return processor;
177 }
178
179
180
181
182
183
184 public void registerForReading(final ProcessorFactory factory) {
185 this.readingFactory.add(factory);
186 }
187
188
189
190
191
192
193 public void registerForWriting(final ProcessorFactory factory) {
194 this.writingFactory.add(factory);
195 }
196
197
198
199
200
201
202
203
204 public <A extends Annotation> void registerForConversion(final Class<A> anno, final ConversionProcessorFactory<A> factory) {
205 this.conversionHandler.register(anno, factory);
206 }
207
208
209
210
211
212
213
214
215 public <A extends Annotation> void registerForConstraint(final Class<A> anno, final ConstraintProcessorFactory<A> factory) {
216 this.constraintHandler.register(anno, factory);
217 }
218
219
220
221
222
223
224
225
226 @SuppressWarnings("unchecked")
227 public TextFormatter<T> getFormatter(final FieldAccessor field, final Configuration config) {
228
229 if(field.hasAnnotation(CsvFormat.class)) {
230 CsvFormat formatAnno = field.getAnnotation(CsvFormat.class).get();
231
232 final TextFormatter<T> formatter = (TextFormatter<T>) config.getBeanFactory().create(formatAnno.formatter());
233 if(!formatAnno.message().isEmpty()) {
234 formatter.setValidationMessage(formatAnno.message());
235 }
236 return formatter;
237
238 } else {
239 return getDefaultFormatter(field, config);
240
241 }
242 }
243
244
245
246
247
248
249
250
251 protected abstract TextFormatter<T> getDefaultFormatter(FieldAccessor field, Configuration config);
252
253
254
255
256
257 public Set<Map.Entry<Class<? extends Annotation>, ConversionProcessorFactory<?>>> getEntrySetForConversion() {
258 return conversionHandler.getEntrySet();
259 }
260
261
262
263
264
265 public Set<Map.Entry<Class<? extends Annotation>, ConstraintProcessorFactory<?>>> getEntrySetForConsraint() {
266 return constraintHandler.getEntrySet();
267 }
268
269 }