1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.orangesignal.csv.io;
18
19 import java.io.Closeable;
20 import java.io.Flushable;
21 import java.io.IOException;
22 import java.lang.reflect.Field;
23 import java.util.Arrays;
24 import java.util.List;
25
26 import com.orangesignal.csv.CsvWriter;
27 import com.orangesignal.csv.bean.CsvColumnNameMappingBeanTemplate;
28 import com.orangesignal.csv.bean.FieldUtils;
29
30
31
32
33
34
35
36 public class CsvColumnNameMappingBeanWriter<T> implements Closeable, Flushable {
37
38
39
40
41 private CsvWriter writer;
42
43
44
45
46 private final CsvColumnNameMappingBeanTemplate<T> template;
47
48
49
50
51
52
53 private final boolean header;
54
55
56
57
58 private List<String> columnNames;
59
60
61
62
63 private int columnCount = -1;
64
65
66
67
68
69
70
71
72
73
74
75
76
77 public static <T> CsvColumnNameMappingBeanWriter<T> newInstance(final CsvWriter writer, final Class<T> type) {
78 return new CsvColumnNameMappingBeanWriter<T>(writer, type);
79 }
80
81
82
83
84
85
86
87
88
89
90
91
92 public static <T> CsvColumnNameMappingBeanWriter<T> newInstance(final CsvWriter writer, final Class<T> type, final boolean header) {
93 return new CsvColumnNameMappingBeanWriter<T>(writer, type, header);
94 }
95
96
97
98
99
100
101
102
103
104
105 public static <T> CsvColumnNameMappingBeanWriter<T> newInstance(final CsvWriter writer, final CsvColumnNameMappingBeanTemplate<T> template) {
106 return new CsvColumnNameMappingBeanWriter<T>(writer, template);
107 }
108
109
110
111
112
113
114
115
116
117
118
119
120 public static <T> CsvColumnNameMappingBeanWriter<T> newInstance(final CsvWriter writer, final CsvColumnNameMappingBeanTemplate<T> template, final boolean header) {
121 return new CsvColumnNameMappingBeanWriter<T>(writer, template, header);
122 }
123
124
125
126
127
128
129
130
131
132
133
134 public CsvColumnNameMappingBeanWriter(final CsvWriter writer, final Class<T> type) {
135 this(writer, new CsvColumnNameMappingBeanTemplate<T>(type), true);
136 }
137
138
139
140
141
142
143
144
145
146
147 public CsvColumnNameMappingBeanWriter(final CsvWriter writer, final Class<T> type, final boolean header) {
148 this(writer, new CsvColumnNameMappingBeanTemplate<T>(type), header);
149 }
150
151
152
153
154
155
156
157
158 public CsvColumnNameMappingBeanWriter(final CsvWriter writer, final CsvColumnNameMappingBeanTemplate<T> template) {
159 this(writer, template, true);
160 }
161
162
163
164
165
166
167
168
169
170
171 public CsvColumnNameMappingBeanWriter(final CsvWriter writer, final CsvColumnNameMappingBeanTemplate<T> template, final boolean header) {
172 if (writer == null) {
173 throw new IllegalArgumentException("CsvWriter must not be null");
174 }
175 if (template == null) {
176 throw new IllegalArgumentException("CsvColumnNameMappingBeanTemplate must not be null");
177 }
178 this.writer = writer;
179 this.template = template;
180 this.header = header;
181 }
182
183
184
185
186
187
188
189 private void ensureOpen() throws IOException {
190 if (writer == null) {
191 throw new IOException("CsvWriter closed");
192 }
193 }
194
195 private void ensureHeader() throws IOException {
196 synchronized (this) {
197 if (columnNames == null) {
198 template.setupColumnMappingIfNeed();
199 final List<String> names = template.createColumnNames();
200 if (header) {
201 writer.writeValues(names);
202 }
203 columnNames = names;
204 columnCount = names.size();
205 }
206 }
207 }
208
209
210
211
212 @Override
213 public void flush() throws IOException {
214 synchronized (this) {
215 ensureOpen();
216 writer.flush();
217 }
218 }
219
220 @Override
221 public void close() throws IOException {
222 synchronized (this) {
223 ensureOpen();
224 writer.close();
225 writer = null;
226 columnNames = null;
227 columnCount = -1;
228 }
229 }
230
231
232
233
234
235
236
237
238
239 public void writeHeader() throws IOException {
240 synchronized (this) {
241 ensureOpen();
242 ensureHeader();
243 }
244 }
245
246
247
248
249
250
251
252
253
254 public boolean write(final T bean) throws IOException {
255 synchronized (this) {
256 ensureOpen();
257 ensureHeader();
258
259
260 if (bean == null) {
261 writer.writeValues(null);
262 return true;
263 }
264
265 final List<String> values = toValues(bean);
266 if (template.isAccept(columnNames, values)) {
267 return false;
268 }
269 writer.writeValues(values);
270 return true;
271 }
272 }
273
274 private List<String> toValues(final T bean) throws IOException {
275 final String[] values = new String[columnCount];
276 for (int i = 0; i < columnCount; i++) {
277 final String columnName = columnNames.get(i);
278 if (columnName == null) {
279 continue;
280 }
281 final String fieldName = template.getFieldName(columnName);
282 if (fieldName == null) {
283 continue;
284 }
285 final Field f = FieldUtils.getField(bean.getClass(), fieldName);
286 values[i] = template.objectToString(columnName, FieldUtils.getFieldValue(bean, f));
287 }
288 return Arrays.asList(values);
289 }
290
291
292
293
294
295
296
297
298
299
300 public CsvColumnNameMappingBeanTemplate<T> getTemplate() {
301 return template;
302 }
303
304 }