1 /* 2 * CSVeed (https://github.com/42BV/CSVeed) 3 * 4 * Copyright 2013-2023 CSVeed. 5 * 6 * All rights reserved. This program and the accompanying materials 7 * are made available under the terms of The Apache Software License, 8 * Version 2.0 which accompanies this distribution, and is available at 9 * https://www.apache.org/licenses/LICENSE-2.0.txt 10 */ 11 package org.csveed.api; 12 13 import java.util.Collection; 14 import java.util.List; 15 import java.util.Locale; 16 17 import org.csveed.bean.AbstractMapper; 18 import org.csveed.bean.conversion.Converter; 19 20 /** 21 * <p> 22 * The CsvClient is responsible for reading/writing CSV rows and converting those into beans/rows. There are a couple of 23 * ways to initialize a {@link org.csveed.api.CsvClientImpl}: 24 * </p> 25 * <ul> 26 * <li>Just use a Reader/Writer. In this case you can only use the row functionality of CSVeed, not the bean 27 * functionality</li> 28 * <li>Pass a Reader or Writer and point it to class. The {@link org.csveed.annotations} in the class are read, as is 29 * the order of the properties within the class.</li> 30 * <li>Pass a Reader or Writer and roll your own instructions. Pass a {@link org.csveed.bean.BeanInstructions} 31 * implementation with your own configuration settings</li> 32 * </ul> 33 * 34 * @param <T> 35 * the bean class into which the rows are converted 36 */ 37 public interface CsvClient<T> { 38 39 /** 40 * Writes a collection of Beans to the table. 41 * 42 * @param beans 43 * beans to write to the table 44 */ 45 void writeBeans(Collection<T> beans); 46 47 /** 48 * Writes a single Bean to the table. 49 * 50 * @param bean 51 * bean to write to the table 52 */ 53 void writeBean(T bean); 54 55 /** 56 * Writes a single row to the table. 57 * 58 * @param row 59 * single row 60 */ 61 void writeRow(Row row); 62 63 /** 64 * Writes a single row (consisting of String cells) to the table. 65 * 66 * @param row 67 * single row 68 * 69 * @return the written row 70 */ 71 Row writeRow(String[] row); 72 73 /** 74 * Writes a collection of rows to the table. 75 * 76 * @param rows 77 * collections of rows 78 */ 79 void writeRows(Collection<Row> rows); 80 81 /** 82 * Writes a two-dimensional array of cells (rows with cells) to the table. 83 * 84 * @param rows 85 * two-dimensional array of cells 86 */ 87 void writeRows(String[][] rows); 88 89 /** 90 * Writes the header to the table. 91 * 92 * @param header 93 * the header row 94 * 95 * @return the converted Header 96 */ 97 Header writeHeader(String[] header); 98 99 /** 100 * Writes the header to the table. 101 * 102 * @param header 103 * the header row 104 */ 105 void writeHeader(Header header); 106 107 /** 108 * Writes a header based on the bean properties to the table. 109 */ 110 void writeHeader(); 111 112 /** 113 * Reads all rows from the file and return these as beans. 114 * 115 * @return all beans read from the Reader 116 */ 117 List<T> readBeans(); 118 119 /** 120 * Reads a single row and returns this as a bean. The RowReader will keep track of its state. 121 * 122 * @return Bean read from the Reader 123 */ 124 T readBean(); 125 126 /** 127 * Reads all rows from the file and returns them as a List. After this, the RowReader will be finished 128 * 129 * @return all Rows read from the Reader 130 */ 131 List<Row> readRows(); 132 133 /** 134 * Reads a single row from the file and returns this. The RowReader will keep track of its state. 135 * 136 * @return Row read from the Reader 137 */ 138 Row readRow(); 139 140 /** 141 * Returns the header of the CSV file. Only possibly returns a value when useHeader==true 142 * 143 * @return header or null if the useHeader==false 144 */ 145 Header readHeader(); 146 147 /** 148 * Returns the line from which the row was read. Note that a line is seen as a legitimate CSV row, not necessarily a 149 * printable line (unless multi-lines are used, these values are the same). 150 * 151 * @return current line number 152 */ 153 int getCurrentLine(); 154 155 /** 156 * States whether the Reader is done with the file. 157 * 158 * @return true if file is finished 159 */ 160 boolean isFinished(); 161 162 /** 163 * Makes sure that the first readable line is interpreted as the header line. That line will not be read as content. 164 * This method is called whenever {@link org.csveed.annotations.CsvFile#useHeader()} is used. The default value for 165 * this setting is true. This call is a facade for {@link org.csveed.row.RowInstructions#setUseHeader(boolean)}. 166 * 167 * @param useHeader 168 * true if the header is interpreted and used 169 * 170 * @return convenience for chaining 171 */ 172 CsvClient<T> setUseHeader(boolean useHeader); 173 174 /** 175 * Sets the start row of the CSV file. If {@link #setUseHeader(boolean)} == true, this will be the header row and 176 * the next ones are all content rows. This method is called whenever 177 * {@link org.csveed.annotations.CsvFile#startRow()} is used. The default value for this setting is 1. This call is 178 * a facade for {@link org.csveed.row.RowInstructions#setStartRow(int)}. 179 * 180 * @param startRow 181 * the first row to start reading, including the header row 182 * 183 * @return convenience for chaining 184 */ 185 CsvClient<T> setStartRow(int startRow); 186 187 /** 188 * Sets the character that will be interpreted as an escape symbol while within a quoted field. This method is 189 * called whenever {@link org.csveed.annotations.CsvFile#escape()} is used. The default value for this setting is a 190 * double quote (") symbol. This call is a facade for {@link org.csveed.row.RowInstructions#setEscape(char)}. 191 * 192 * @param symbol 193 * the symbol to use for escaping characters within a quoted field 194 * 195 * @return convenience for chaining 196 */ 197 CsvClient<T> setEscape(char symbol); 198 199 /** 200 * Sets the character that will be interpreted as a quote symbol, signifying either the start or the end of a quoted 201 * field. This method is called whenever {@link org.csveed.annotations.CsvFile#quote()} is used. The default value 202 * for this setting is a double quote (") symbol. This call is a facade for 203 * {@link org.csveed.row.RowInstructions#setQuote(char)}. 204 * 205 * @param symbol 206 * the symbol to use for indicating start/end of a quoted field 207 * 208 * @return convenience for chaining 209 */ 210 CsvClient<T> setQuote(char symbol); 211 212 /** 213 * Sets the character that will be interpreted as a separator between cells. This method is called whenever 214 * {@link org.csveed.annotations.CsvFile#separator()} is used. The default value for this setting is a semi-colon 215 * (;). This call is a facade for {@link org.csveed.row.RowInstructions#setSeparator(char)}. 216 * 217 * @param symbol 218 * the symbol to use as a separator between cells 219 * 220 * @return convenience for chaining 221 */ 222 CsvClient<T> setSeparator(char symbol); 223 224 /** 225 * Sets the character that will be interpreted as a comment field on the first position of a row. This method is 226 * called whenever {@link org.csveed.annotations.CsvFile#comment()} is used. The default value for this setting is a 227 * hashtag (#). 228 * 229 * @param symbol 230 * the symbol to use as the 0-position comment marker 231 * 232 * @return convenience for chaining 233 */ 234 CsvClient<T> setComment(char symbol); 235 236 /** 237 * Sets the characters (plural) that will be interpreted as end-of-line markers (unless within a quoted field). This 238 * method is called whenever {@link org.csveed.annotations.CsvFile#endOfLine()} is used. The default values for this 239 * setting are \r and \n. This call is a facade for {@link org.csveed.row.RowInstructions#setEndOfLine(char[])}. 240 * 241 * @param symbols 242 * the symbol to interpret as end-of-line markers (unless within a quoted field) 243 * 244 * @return convenience for chaining 245 */ 246 CsvClient<T> setEndOfLine(char[] symbols); 247 248 /** 249 * Determines whether empty lines must be skipped or treated as single-column rows. This method is called whenever 250 * {@link org.csveed.annotations.CsvFile#skipEmptyLines()} is used. The default value for this setting is to skip 251 * the empty lines. 252 * 253 * @param skip 254 * true to skip empty lines, false to treat as single-column rows 255 * 256 * @return convenience for chaining 257 */ 258 CsvClient<T> skipEmptyLines(boolean skip); 259 260 /** 261 * Determines whether comment lines must be skipped. This method is called whenever 262 * {@link org.csveed.annotations.CsvFile#skipCommentLines()} is used. The default value for this setting is to skip 263 * comment lines. This method exists to guarantee that lines are not accidentally treated as comment lines. 264 * 265 * @param skip 266 * true to skip comment lines, identified as starting with a comment marker 267 * 268 * @return convenience for chaining 269 */ 270 CsvClient<T> skipCommentLines(boolean skip); 271 272 /** 273 * A file can have a special layout with a dynamic number of columns. If the intention is to duplicate rows for 274 * every separate column, this is the method you require. It will remember the start position of the dynamic columns 275 * and treat every column after that as dynamic. For every dynamic column a row will be created. If a bean has 276 * fields annotated with @CsvHeaderName or @CsvHeaderValue, it will store the values of the header or the cell for 277 * that index column in the fields. 278 * 279 * @param startIndex 280 * the index where the dynamic columns start 281 * 282 * @return convenience for chaining 283 */ 284 CsvClient<T> setStartIndexDynamicColumns(int startIndex); 285 286 /** 287 * Determines which mapping strategy is to be employed for mapping cells to bean properties. This method is called 288 * whenever {@link org.csveed.annotations.CsvFile#mappingStrategy()} is used. The default mapping strategy is 289 * {@link org.csveed.bean.ColumnIndexMapper}, which looks at either the position of a property within the class or 290 * the custom index if {@link org.csveed.annotations.CsvCell#columnIndex()} or 291 * {@link #mapColumnIndexToProperty(int, String)} has been set. 292 * 293 * @param mapper 294 * the mapping strategy to employ for mapping cells to bean properties 295 * 296 * @return convenience for chaining 297 */ 298 CsvClient<T> setMapper(Class<? extends AbstractMapper> mapper); 299 300 /** 301 * Determines what dateformat to apply to the cell value before storing it as a date. This method is called whenever 302 * {@link org.csveed.annotations.CsvDate} is used. The default for date format is dd-MM-yyyy. 303 * 304 * @param propertyName 305 * the name of the property to write the date to 306 * @param dateFormat 307 * the date format to apply for parsing the date value 308 * 309 * @return convenience for chaining 310 */ 311 CsvClient<T> setDate(String propertyName, String dateFormat); 312 313 /** 314 * Determines what Locale to apply to the cell value before converting it to a number. This method is called 315 * whenever {@link org.csveed.annotations.CsvLocalizedNumber} is used. The default for Locale is the Locale of the 316 * server. 317 * 318 * @param propertyName 319 * the name of the property to write the data to 320 * @param locale 321 * the Locale to apply for converting the number 322 * 323 * @return convenience for chaining 324 */ 325 CsvClient<T> setLocalizedNumber(String propertyName, Locale locale); 326 327 /** 328 * Determines if the field is required. If so, the cell may not be empty and a 329 * {@link org.csveed.report.CsvException} will be thrown if this occurs. This method is called whenever 330 * {@link org.csveed.annotations.CsvCell#required()} is used. The default for a property is false. 331 * 332 * @param propertyName 333 * property for which the requirement applies 334 * @param required 335 * whether the cell must be not-null 336 * 337 * @return convenience for chaining 338 */ 339 CsvClient<T> setRequired(String propertyName, boolean required); 340 341 /** 342 * Sets a custom {@link java.beans.PropertyEditor} for the property. This PropertyEditor is called to convert the 343 * text to the type of the property and set it on the bean. This method is called whenever 344 * {@link org.csveed.annotations.CsvConverter#converter()} is used. The default for a property is based on the 345 * wonderful set of PropertyEditors that Spring offers, which is all basics and some extras as well. 346 * 347 * @param propertyName 348 * property to which the converter must be applied 349 * @param converter 350 * PropertyEditor to apply to the property 351 * 352 * @return convenience for chaining 353 */ 354 CsvClient<T> setConverter(String propertyName, Converter converter); 355 356 /** 357 * Sets a field to be ignored for purposes of mapping. This method is called whenever 358 * {@link org.csveed.annotations.CsvIgnore} is used. By default none of the fields are ignored unless, custom 359 * instructions are used. In this case, all fields are ignored by default. 360 * 361 * @param propertyName 362 * property which must be ignored for mapping 363 * 364 * @return convenience for chaining 365 */ 366 CsvClient<T> ignoreProperty(String propertyName); 367 368 /** 369 * Maps a column in the CSV to a specific property. This method is called whenever 370 * {@link org.csveed.annotations.CsvCell#columnIndex()} is used. By default there is NO mapping when custom 371 * instructions are used, so you should roll your own. Note that column indexes are 1-based, not 0-based. 372 * 373 * @param columnIndex 374 * index of the column for which the property mapping must be applied 375 * @param propertyName 376 * property to which the index-based mapping must be applied 377 * 378 * @return convenience for chaining 379 */ 380 CsvClient<T> mapColumnIndexToProperty(int columnIndex, String propertyName); 381 382 /** 383 * Maps a column name (which is found in the header) to a specific property. Note that to use this, headers must be 384 * enabled. This method is called whenever {@link org.csveed.annotations.CsvCell#columnName()} is used. By default 385 * there is NO mapping when custom instructions are used, so you should roll your own. Also, don't forget to 386 * {@link #setMapper(Class)} to {@link org.csveed.bean.ColumnNameMapper} for this to work. 387 * 388 * @param columnName 389 * name of the column for which the property mapping must be applied 390 * @param propertyName 391 * property to which the name-based mapping must be applied 392 * 393 * @return convenience for chaining 394 */ 395 CsvClient<T> mapColumnNameToProperty(String columnName, String propertyName); 396 397 /** 398 * Determines what property will receive the header name in the currently active dynamic column. 399 * 400 * @param propertyName 401 * property in which the active dynamic header name must be stored 402 * 403 * @return convenience for chaining 404 */ 405 CsvClient<T> setHeaderNameToProperty(String propertyName); 406 407 /** 408 * Determines what property will receive the cell value in the currently active dynamic column. 409 * 410 * @param propertyName 411 * property in which the active dynamic column value must be stored 412 * 413 * @return convenience for chaining 414 */ 415 CsvClient<T> setHeaderValueToProperty(String propertyName); 416 417 }