1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.supercsv.io;
17
18 import java.io.IOException;
19 import java.io.Reader;
20 import java.lang.reflect.Method;
21 import java.util.ArrayList;
22 import java.util.List;
23
24 import org.supercsv.cellprocessor.ift.CellProcessor;
25 import org.supercsv.exception.SuperCsvConstraintViolationException;
26 import org.supercsv.exception.SuperCsvException;
27 import org.supercsv.exception.SuperCsvReflectionException;
28 import org.supercsv.prefs.CsvPreference;
29 import org.supercsv.util.BeanInterfaceProxy;
30 import org.supercsv.util.MethodCache;
31
32
33
34
35
36
37
38
39
40
41 public class CsvBeanReader extends AbstractCsvReader implements ICsvBeanReader {
42
43
44 private final List<Object> processedColumns = new ArrayList<Object>();
45
46
47 private final MethodCache cache = new MethodCache();
48
49
50
51
52
53
54
55
56
57
58
59
60 public CsvBeanReader(final Reader reader, final CsvPreference preferences) {
61 super(reader, preferences);
62 }
63
64
65
66
67
68
69
70
71
72
73
74
75 public CsvBeanReader(final ITokenizer tokenizer, final CsvPreference preferences) {
76 super(tokenizer, preferences);
77 }
78
79
80
81
82
83
84
85
86
87
88
89 private static <T> T instantiateBean(final Class<T> clazz) {
90 final T bean;
91 if( clazz.isInterface() ) {
92 bean = BeanInterfaceProxy.createProxy(clazz);
93 } else {
94 try {
95 bean = clazz.newInstance();
96 }
97 catch(InstantiationException e) {
98 throw new SuperCsvReflectionException(String.format(
99 "error instantiating bean, check that %s has a default no-args constructor", clazz.getName()), e);
100 }
101 catch(IllegalAccessException e) {
102 throw new SuperCsvReflectionException("error instantiating bean", e);
103 }
104 }
105
106 return bean;
107 }
108
109
110
111
112
113
114
115
116
117
118
119
120
121 private static void invokeSetter(final Object bean, final Method setMethod, final Object fieldValue) {
122 try {
123 setMethod.invoke(bean, fieldValue);
124 }
125 catch(final Exception e) {
126 throw new SuperCsvReflectionException(String.format("error invoking method %s()", setMethod.getName()), e);
127 }
128 }
129
130
131
132
133
134
135
136
137
138
139
140
141 private <T> T populateBean(final T resultBean, final String[] nameMapping) {
142
143
144 for( int i = 0; i < nameMapping.length; i++ ) {
145
146 final Object fieldValue = processedColumns.get(i);
147
148
149 if( nameMapping[i] == null || fieldValue == null ) {
150 continue;
151 }
152
153
154 Method setMethod = cache.getSetMethod(resultBean, nameMapping[i], fieldValue.getClass());
155 invokeSetter(resultBean, setMethod, fieldValue);
156
157 }
158
159 return resultBean;
160 }
161
162
163
164
165 public <T> T read(final Class<T> clazz, final String... nameMapping) throws IOException {
166
167 if( clazz == null ) {
168 throw new NullPointerException("clazz should not be null");
169 } else if( nameMapping == null ) {
170 throw new NullPointerException("nameMapping should not be null");
171 }
172
173 return readIntoBean(instantiateBean(clazz), nameMapping, null);
174 }
175
176
177
178
179 public <T> T read(final Class<T> clazz, final String[] nameMapping, final CellProcessor... processors)
180 throws IOException {
181
182 if( clazz == null ) {
183 throw new NullPointerException("clazz should not be null");
184 } else if( nameMapping == null ) {
185 throw new NullPointerException("nameMapping should not be null");
186 } else if( processors == null ) {
187 throw new NullPointerException("processors should not be null");
188 }
189
190 return readIntoBean(instantiateBean(clazz), nameMapping, processors);
191 }
192
193
194
195
196 public <T> T read(final T bean, final String... nameMapping) throws IOException {
197
198 if( bean == null ) {
199 throw new NullPointerException("bean should not be null");
200 } else if( nameMapping == null ) {
201 throw new NullPointerException("nameMapping should not be null");
202 }
203
204 return readIntoBean(bean, nameMapping, null);
205 }
206
207
208
209
210 public <T> T read(final T bean, final String[] nameMapping, final CellProcessor... processors) throws IOException {
211 if( bean == null ) {
212 throw new NullPointerException("bean should not be null");
213 } else if( nameMapping == null ) {
214 throw new NullPointerException("nameMapping should not be null");
215 } else if( processors == null ) {
216 throw new NullPointerException("processors should not be null");
217 }
218
219 return readIntoBean(bean, nameMapping, processors);
220 }
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246 private <T> T readIntoBean(final T bean, final String[] nameMapping, final CellProcessor[] processors)
247 throws IOException {
248
249 if( readRow() ) {
250 if( nameMapping.length != length() ) {
251 throw new IllegalArgumentException(String.format(
252 "the nameMapping array and the number of columns read "
253 + "should be the same size (nameMapping length = %d, columns = %d)", nameMapping.length,
254 length()));
255 }
256
257 if( processors == null ) {
258 processedColumns.clear();
259 processedColumns.addAll(getColumns());
260 } else {
261 executeProcessors(processedColumns, processors);
262 }
263
264 return populateBean(bean, nameMapping);
265 }
266
267 return null;
268 }
269
270 }