1 /*
2 * Copyright 2012 Olivier Godineau
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
6 * the License at http://www.apache.org/licenses/LICENSE-2.0
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 * License for the specific language governing permissions and limitations under
12 * the License.
13 */
14 package olg.csv.bean;
15
16 import java.io.Closeable;
17 import java.io.File;
18 import java.io.IOException;
19
20 import olg.csv.base.IWriter;
21 import olg.csv.base.IgnoreNullWriter;
22 import olg.csv.base.Row;
23 import olg.csv.bean.impl.RowProcessor;
24 import olg.csv.bean.loader.CellProcessorLoader;
25 import olg.csv.bean.loader.LoadException;
26
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 /**
31 * Class specialized in writing objects into a file Used a IWriter to write a
32 * list of Strings into a file Uses a list of PropertyFormatter to transform an
33 * <code>E</code> object into a list of Strings.
34 *
35 * @author Olivier Godineau
36 *
37 * @param <E>
38 * object this writer deals with.
39 * @see IWriter
40 * @see olg.csv.bean.impl.PropertyFormatter
41 */
42 public class BeanWriter<E> implements Closeable {
43 /**
44 * The class logger.
45 */
46 private static final Logger LOGGER = LoggerFactory.getLogger(BeanWriter.class);
47 /**
48 * the writer. Allows to write a list of Strings on a dedicated output.
49 */
50 private final IWriter baseWriter;
51
52 /**
53 * The row processor.
54 */
55 private final IRowProcessor<E> rowProcessor;
56
57 /**
58 *
59 * @param configFile
60 * the file which describes how to load the field formatters used
61 * to transform an object into a list of Strings. XML
62 * Configuration must be a bean-writer or bean-row XML type, See
63 * bean-row.xsd file. Must be not <code>null</code>.
64 * @param writer
65 * Allows to write a list of Strings on a dedicated output. Must
66 * be not <code>null</code>.
67 * @throws LoadException
68 * if an error occurs during loading field formatters from file
69 */
70 public BeanWriter(File configFile, IWriter writer) throws LoadException {
71 this(configFile, writer, false);
72
73 }
74
75 /**
76 *
77 * @param configFile
78 * the file which describe how to load the field formatters used
79 * to transform an object into a list of Strings. XML
80 * Configuration must be a bean-writer or bean-row XML type, See
81 * bean-row.xsd file. Must be not <code>null</code>.
82 * @param writer
83 * Allows to write a list of Strings on a dedicated output. Must
84 * be not <code>null</code>.
85 * @param skipEmptyRow
86 * if true avoids writing blank lines.
87 * @throws LoadException
88 * if an error occurs during loading field formatters from file.
89 */
90 public BeanWriter(File configFile, IWriter writer, boolean skipEmptyRow) throws LoadException {
91 super();
92 if (configFile == null) {
93 throw new IllegalArgumentException("BeanWriter Constructor configFile argument must be not null");
94 }
95 if (writer == null) {
96 throw new IllegalArgumentException("BeanWriter Constructor writer argument must be not null");
97 }
98 if (skipEmptyRow) {
99 this.baseWriter = new IgnoreNullWriter(writer);
100 } else {
101 this.baseWriter = writer;
102 }
103 this.rowProcessor = new RowProcessor<E>(new CellProcessorLoader<E>().load(configFile));
104 if (this.baseWriter.isWithHeaders()) {
105 this.baseWriter.addRow(this.rowProcessor.getHeaders());
106 }
107
108 }
109
110 /**
111 * Construct a BeanWriter with a rowProcessor and a writer.
112 *
113 * @param rowProcessor
114 * the rowProcessor. If the rowProcessor products empty rows,
115 * blank lines are copied into the file.To avoid this case, use
116 * IgnoreNullWriter. Must be not <code>null</code>.
117 * @param writer
118 * the writer.
119 */
120 public BeanWriter(IRowProcessor<E> rowProcessor, IWriter writer) {
121 super();
122 if (rowProcessor == null) {
123 throw new IllegalArgumentException("BeanWriter Constructor rowProcessor argument must be not null");
124 }
125 if (writer == null) {
126 throw new IllegalArgumentException("BeanWriter Constructor writer argument must be not null");
127 }
128 this.baseWriter = writer;
129 this.rowProcessor = rowProcessor;
130 if (this.baseWriter.isWithHeaders()) {
131 this.baseWriter.addRow(this.rowProcessor.getHeaders());
132 }
133 }
134
135 /**
136 * {@inheritDoc}
137 */
138 public void close() {
139 try {
140 baseWriter.close();
141 } catch (IOException e) {
142 LOGGER.info("Error on closing IWriter", e);
143 }
144 }
145
146 /**
147 * Writes a bean on a dedicated output.
148 * <p>
149 * Throws PropertyException if error occurs during property extraction and
150 * formatting.
151 * </p>
152 *
153 * <p>
154 * Throws WriterException if I/O error occurs during writing.
155 * </p>
156 *
157 * @param element
158 * the bean to write. Must be not <code>null</code>.
159 */
160 public void write(E element) throws PropertyException {
161 if (element == null) {
162 throw new IllegalArgumentException("element argument must be not null");
163 }
164
165 Row row = rowProcessor.transform(element);
166 baseWriter.addRow(row);
167
168 }
169
170 /**
171 * Allows to write a header line to describe the fields.
172 *
173 * <p>
174 * if the configuration file from which this beanWriter is defined is the
175 * bean-writer element, try to take the declared name of the column
176 * otherwise use "column_"i where i is the column num.
177 * </p>
178 * <p>
179 * if the configuration file from which this beanWriter is defined is the
180 * bean-row element, try to take the name of the declared column, otherwise
181 * use the name of the corresponding property.
182 *
183 * <p>
184 * throws WriterException if this method is called after objects had been
185 * wroten or I/O error occurs.
186 * </p>
187 */
188 public void writeHeaders() {
189
190 baseWriter.addRow(rowProcessor.getHeaders());
191 }
192
193 }