1 package com.github.mygreen.supercsv.builder;
2
3 import java.util.List;
4 import java.util.Optional;
5 import java.util.TreeSet;
6 import java.util.stream.Collectors;
7
8 import org.supercsv.exception.SuperCsvException;
9
10 import com.github.mygreen.supercsv.annotation.CsvColumn;
11 import com.github.mygreen.supercsv.annotation.CsvPartial;
12 import com.github.mygreen.supercsv.annotation.conversion.CsvFixedSize;
13 import com.github.mygreen.supercsv.cellprocessor.conversion.PaddingProcessor;
14 import com.github.mygreen.supercsv.exception.SuperCsvInvalidAnnotationException;
15 import com.github.mygreen.supercsv.io.LazyCsvAnnotationBeanReader;
16 import com.github.mygreen.supercsv.io.LazyCsvAnnotationBeanWriter;
17 import com.github.mygreen.supercsv.localization.MessageBuilder;
18
19
20
21
22
23
24
25
26
27 public class BeanMappingFactoryHelper {
28
29
30
31
32
33
34
35
36 public static TreeSet<Integer> validateDuplicatedColumnNumber(final Class<?> beanType, final List<ColumnMapping> list) {
37
38 final TreeSet<Integer> checkedNumber = new TreeSet<>();
39 final TreeSet<Integer> duplicatedNumbers = new TreeSet<>();
40 for(ColumnMapping columnMapping : list) {
41
42 if(checkedNumber.contains(columnMapping.getNumber())) {
43 duplicatedNumbers.add(columnMapping.getNumber());
44 }
45 checkedNumber.add(columnMapping.getNumber());
46
47 }
48
49 if(!duplicatedNumbers.isEmpty()) {
50
51 throw new SuperCsvInvalidAnnotationException(MessageBuilder.create("anno.attr.duplicated")
52 .var("property", beanType.getName())
53 .varWithAnno("anno", CsvColumn.class)
54 .var("attrName", "number")
55 .var("attrValues", duplicatedNumbers)
56 .format());
57 }
58
59
60 final int minColumnNumber = checkedNumber.first();
61 if(minColumnNumber <= 0) {
62 throw new SuperCsvInvalidAnnotationException(MessageBuilder.create("anno.attr.min")
63 .var("property", beanType.getName())
64 .varWithAnno("anno", CsvColumn.class)
65 .var("attrName", "number")
66 .var("attrValue", minColumnNumber)
67 .var("min", 1)
68 .format());
69
70 }
71
72 return checkedNumber;
73 }
74
75
76
77
78
79
80
81
82
83
84 public static TreeSet<Integer> supplyLackedNumberMappingColumn(final Class<?> beanType, final List<ColumnMapping> list,
85 final Optional<CsvPartial> partialAnno, final String[] suppliedHeaders, final Configuration configuration) {
86
87 final TreeSet<Integer> checkedNumber = list.stream()
88 .filter(col -> col.isDeterminedNumber())
89 .map(col -> col.getNumber())
90 .collect(Collectors.toCollection(TreeSet::new));
91
92
93 final int maxColumnNumber = checkedNumber.last();
94
95
96 final TreeSet<Integer> lackedNumbers = new TreeSet<Integer>();
97 for(int i=1; i <= maxColumnNumber; i++) {
98 if(!checkedNumber.contains(i)) {
99 lackedNumbers.add(i);
100 }
101 }
102
103
104 if(partialAnno.isPresent()) {
105
106 final int partialColumnSize = partialAnno.get().columnSize();
107 if(maxColumnNumber > partialColumnSize) {
108 throw new SuperCsvInvalidAnnotationException(partialAnno.get(), MessageBuilder.create("anno.CsvPartial.columSizeMin")
109 .var("property", beanType.getName())
110 .var("columnSize", partialColumnSize)
111 .var("maxColumnNumber", maxColumnNumber)
112 .format());
113
114 }
115
116 if(maxColumnNumber < partialColumnSize) {
117 for(int i= maxColumnNumber+1; i <= partialColumnSize; i++) {
118 lackedNumbers.add(i);
119 }
120 }
121
122 }
123
124
125 if(lackedNumbers.size() > 0) {
126
127 for(int number : lackedNumbers) {
128 list.add(createPartialColumnMapping(number, partialAnno, getSuppliedHeaders(suppliedHeaders, number), configuration));
129 }
130
131 list.sort(null);
132 }
133
134 return lackedNumbers;
135
136 }
137
138
139
140
141
142
143
144 private static Optional<String> getSuppliedHeaders(final String[] suppliedHeaders, final int columnNumber) {
145
146 final int length = suppliedHeaders.length;
147 if(length == 0) {
148 return Optional.empty();
149 }
150
151 if(columnNumber < length) {
152 return Optional.ofNullable(suppliedHeaders[columnNumber-1]);
153 }
154
155 return Optional.empty();
156
157 }
158
159
160
161
162
163
164
165
166
167 private static ColumnMapping createPartialColumnMapping(int columnNumber, final Optional<CsvPartial> partialAnno,
168 final Optional<String> suppliedHeader, final Configuration configuration) {
169
170 final ColumnMappingumnMapping.html#ColumnMapping">ColumnMapping columnMapping = new ColumnMapping();
171 columnMapping.setNumber(columnNumber);
172 columnMapping.setPartialized(true);
173
174 String label = String.format("column%d", columnNumber);
175 if(suppliedHeader.isPresent()) {
176 label = suppliedHeader.get();
177 }
178
179 Optional<CsvFixedSize> fixedSizeAnno = Optional.empty();
180
181 if(partialAnno.isPresent()) {
182 for(CsvPartial.Header header : partialAnno.get().headers()) {
183 if(header.number() == columnNumber) {
184 label = header.label();
185
186 if(header.fixedSize().length > 0) {
187
188 fixedSizeAnno = Optional.ofNullable(header.fixedSize()[0]);
189 }
190 break;
191 }
192 }
193 }
194
195 columnMapping.setLabel(label);
196
197 if(fixedSizeAnno.isPresent()) {
198 FixedSizeColumnProperty fixedSizeProperty = createFixedSizeColumnProperty(fixedSizeAnno.get(), configuration);
199 columnMapping.setFixedSizeProperty(fixedSizeProperty);
200 }
201
202 return columnMapping;
203
204 }
205
206
207
208
209
210
211
212
213
214
215
216
217
218 public static void validateNonDeterminedColumnNumber(final Class<?> beanType, final List<ColumnMapping> list,
219 String[] headers) {
220
221 final List<String> nonDeterminedLabels = list.stream()
222 .filter(col -> !col.isDeterminedNumber())
223 .map(col -> col.getLabel())
224 .collect(Collectors.toList());
225
226 if(!nonDeterminedLabels.isEmpty()) {
227
228 throw new SuperCsvException(MessageBuilder.create("lazy.noDeteminedColumns")
229 .var("property", beanType.getName())
230 .var("labels", nonDeterminedLabels)
231 .var("headers", headers)
232 .format());
233
234 }
235
236 }
237
238
239
240
241
242
243
244
245
246 public static FixedSizeColumnProperty createFixedSizeColumnProperty(final CsvFixedSize fixedAnno, final Configuration configuration) {
247
248 FixedSizeColumnPropertyoperty.html#FixedSizeColumnProperty">FixedSizeColumnProperty fixedSizeProperty = new FixedSizeColumnProperty(fixedAnno.size());
249 fixedSizeProperty.setPadChar(fixedAnno.padChar());
250 fixedSizeProperty.setChopped(fixedAnno.chopped());
251 fixedSizeProperty.setRightAlign(fixedAnno.rightAlign());
252
253 fixedSizeProperty.setPaddingProcessor((PaddingProcessor)configuration.getBeanFactory().create(fixedAnno.paddingProcessor()));
254
255 return fixedSizeProperty;
256 }
257
258 }