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 }