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