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.ArrayList;
24 import java.util.Arrays;
25 import java.util.Collections;
26 import java.util.List;
27
28 import com.orangesignal.csv.CsvWriter;
29 import com.orangesignal.csv.bean.CsvBeanTemplate;
30 import com.orangesignal.csv.bean.FieldUtils;
31
32
33
34
35
36
37
38 public class CsvBeanWriter<T> implements Closeable, Flushable {
39
40
41
42
43 private CsvWriter writer;
44
45
46
47
48 private final CsvBeanTemplate<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
66
67
68
69
70
71
72
73
74 public static <T> CsvBeanWriter<T> newInstance(final CsvWriter writer, final Class<T> type) {
75 return new CsvBeanWriter<T>(writer, type);
76 }
77
78
79
80
81
82
83
84
85
86
87
88
89 public static <T> CsvBeanWriter<T> newInstance(final CsvWriter writer, final Class<T> type, final boolean header) {
90 return new CsvBeanWriter<T>(writer, type, header);
91 }
92
93
94
95
96
97
98
99
100
101
102 public static <T> CsvBeanWriter<T> newInstance(final CsvWriter writer, final CsvBeanTemplate<T> template) {
103 return new CsvBeanWriter<T>(writer, template);
104 }
105
106
107
108
109
110
111
112
113
114
115
116
117 public static <T> CsvBeanWriter<T> newInstance(final CsvWriter writer, final CsvBeanTemplate<T> template, final boolean header) {
118 return new CsvBeanWriter<T>(writer, template, header);
119 }
120
121
122
123
124
125
126
127
128
129
130
131 public CsvBeanWriter(final CsvWriter writer, final Class<T> type) {
132 this(writer, new CsvBeanTemplate<T>(type), true);
133 }
134
135
136
137
138
139
140
141
142
143
144 public CsvBeanWriter(final CsvWriter writer, final Class<T> type, final boolean header) {
145 this(writer, new CsvBeanTemplate<T>(type), header);
146 }
147
148
149
150
151
152
153
154
155 public CsvBeanWriter(final CsvWriter writer, final CsvBeanTemplate<T> template) {
156 this(writer, template, true);
157 }
158
159
160
161
162
163
164
165
166
167
168 public CsvBeanWriter(final CsvWriter writer, final CsvBeanTemplate<T> template, final boolean header) {
169 if (writer == null) {
170 throw new IllegalArgumentException("CsvWriter must not be null");
171 }
172 if (template == null) {
173 throw new IllegalArgumentException("CsvBeanTemplate must not be null");
174 }
175 this.writer = writer;
176 this.template = template;
177 this.header = header;
178 }
179
180
181
182
183
184
185
186 private void ensureOpen() throws IOException {
187 if (writer == null) {
188 throw new IOException("CsvWriter closed");
189 }
190 }
191
192 private void ensureHeader() throws IOException {
193 synchronized (this) {
194 if (columnNames == null) {
195 final List<String> names = new ArrayList<String>();
196 for (final Field f : template.getType().getDeclaredFields()) {
197 final String name = f.getName();
198 if (template.isTargetName(name)) {
199 names.add(name);
200 }
201 }
202 if (header) {
203 writer.writeValues(names);
204 }
205 columnNames = Collections.unmodifiableList(names);
206 }
207 }
208 }
209
210
211
212
213 @Override
214 public void flush() throws IOException {
215 synchronized (this) {
216 ensureOpen();
217 writer.flush();
218 }
219 }
220
221 @Override
222 public void close() throws IOException {
223 synchronized (this) {
224 ensureOpen();
225 writer.close();
226 writer = null;
227 columnNames = null;
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 int columnCount = columnNames.size();
276 final String[] values = new String[columnCount];
277 for (int i = 0; i < columnCount; i++) {
278 final String name = columnNames.get(i);
279 if (name == null) {
280 continue;
281 }
282 final Field f = FieldUtils.getField(bean.getClass(), name);
283 values[i] = template.objectToString(name, FieldUtils.getFieldValue(bean, f));
284 }
285 return Arrays.asList(values);
286 }
287
288
289
290
291
292
293
294
295
296
297 public CsvBeanTemplate<T> getTemplate() {
298 return template;
299 }
300
301 }