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