View Javadoc
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 }