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.bean;
12
13 import java.beans.PropertyEditor;
14 import java.util.Locale;
15
16 import org.csveed.bean.conversion.Converter;
17 import org.csveed.common.Column;
18 import org.csveed.row.RowInstructions;
19
20 /**
21 * These instructions are used to power the {@link BeanReader}. Note that the instructions are also used internally if
22 * annotations are used.
23 */
24 public interface BeanInstructions {
25
26 /**
27 * Makes sure that the first readable line is interpreted as the header line. That line will not be read as content.
28 * This method is called whenever {@link org.csveed.annotations.CsvFile#useHeader()} is used. The default value for
29 * this setting is true. This call is a facade for {@link org.csveed.row.RowInstructions#setUseHeader(boolean)}.
30 *
31 * @param useHeader
32 * true if the header is interpreted and used
33 *
34 * @return convenience for chaining
35 */
36 BeanInstructions setUseHeader(boolean useHeader);
37
38 /**
39 * Sets the start row of the CSV file. If {@link #setUseHeader(boolean)} == true, this will be the header row and
40 * the next ones are all content rows. This method is called whenever
41 * {@link org.csveed.annotations.CsvFile#startRow()} is used. The default value for this setting is 1. This call is
42 * a facade for {@link org.csveed.row.RowInstructions#setStartRow(int)}.
43 *
44 * @param startRow
45 * the first row to start reading, including the header row
46 *
47 * @return convenience for chaining
48 */
49 BeanInstructions setStartRow(int startRow);
50
51 /**
52 * Sets the character that will be interpreted as an escape symbol while within a quoted field. This method is
53 * called whenever {@link org.csveed.annotations.CsvFile#escape()} is used. The default value for this setting is a
54 * double quote (") symbol. This call is a facade for {@link org.csveed.row.RowInstructions#setEscape(char)}.
55 *
56 * @param symbol
57 * the symbol to use for escaping characters within a quoted field
58 *
59 * @return convenience for chaining
60 */
61 BeanInstructions setEscape(char symbol);
62
63 /**
64 * Sets the character that will be interpreted as a quote symbol, signifying either the start or the end of a quoted
65 * field. This method is called whenever {@link org.csveed.annotations.CsvFile#quote()} is used. The default value
66 * for this setting is a double quote (") symbol. This call is a facade for
67 * {@link org.csveed.row.RowInstructions#setQuote(char)}.
68 *
69 * @param symbol
70 * the symbol to use for indicating start/end of a quoted field
71 *
72 * @return convenience for chaining
73 */
74 BeanInstructions setQuote(char symbol);
75
76 /**
77 * Sets whether or not quotes are written around the field values. If enabled, the character set as the escape
78 * symbol will be disabled. If disabled, no quotes are written around the field values and the escape symbol is not
79 * escaped. This setting has <strong>no</strong> effect when reading CSV files, only when writing them.
80 *
81 * @param enabled
82 * whether or not to put quotes around fields
83 *
84 * @return convenience for chaining
85 */
86 BeanInstructions setQuotingEnabled(boolean enabled);
87
88 /**
89 * Sets the character that will be interpreted as a separator between cells. This method is called whenever
90 * {@link org.csveed.annotations.CsvFile#separator()} is used. The default value for this setting is a semi-colon
91 * (;). This call is a facade for {@link org.csveed.row.RowInstructions#setSeparator(char)}.
92 *
93 * @param symbol
94 * the symbol to use as a separator between cells
95 *
96 * @return convenience for chaining
97 */
98 BeanInstructions setSeparator(char symbol);
99
100 /**
101 * Sets the character that will be interpreted as a comment field on the first position of a row. This method is
102 * called whenever {@link org.csveed.annotations.CsvFile#comment()} is used. The default value for this setting is a
103 * hashtag (#).
104 *
105 * @param symbol
106 * the symbol to use as the 0-position comment marker
107 *
108 * @return convenience for chaining
109 */
110 BeanInstructions setComment(char symbol);
111
112 /**
113 * Sets the characters (plural) that will be interpreted as end-of-line markers (unless within a quoted field). This
114 * method is called whenever {@link org.csveed.annotations.CsvFile#endOfLine()} is used. The default values for this
115 * setting are \r and \n. This call is a facade for {@link org.csveed.row.RowInstructions#setEndOfLine(char[])}.
116 *
117 * @param symbols
118 * the symbol to interpret as end-of-line markers (unless within a quoted field)
119 *
120 * @return convenience for chaining
121 */
122 BeanInstructions setEndOfLine(char[] symbols);
123
124 /**
125 * Determines whether empty lines must be skipped or treated as single-column rows. This method is called whenever
126 * {@link org.csveed.annotations.CsvFile#skipEmptyLines()} is used. The default value for this setting is to skip
127 * the empty lines.
128 *
129 * @param skip
130 * true to skip empty lines, false to treat as single-column rows
131 *
132 * @return convenience for chaining
133 */
134 BeanInstructions skipEmptyLines(boolean skip);
135
136 /**
137 * Determines whether comment lines must be skipped. This method is called whenever
138 * {@link org.csveed.annotations.CsvFile#skipCommentLines()} is used. The default value for this setting is to skip
139 * comment lines. This method exists to guarantee that lines are not accidentally treated as comment lines.
140 *
141 * @param skip
142 * true to skip comment lines, identified as starting with a comment marker
143 *
144 * @return convenience for chaining
145 */
146 BeanInstructions skipCommentLines(boolean skip);
147
148 /**
149 * A file can have a special layout with a dynamic number of columns. If the intention is to duplicate rows for
150 * every separate column, this is the method you require. It will remember the start position of the dynamic columns
151 * and treat every column after that as dynamic. For every dynamic column a row will be created. If a bean has
152 * fields annotated with @CsvHeaderName or @CsvHeaderValue, it will store the values of the header or the cell for
153 * that index column in the fields.
154 *
155 * @param startIndex
156 * start index of dynamic columns
157 *
158 * @return convenience for chaining
159 */
160 BeanInstructions setStartIndexDynamicColumns(int startIndex);
161
162 /**
163 * Determines which mapping strategy is to be employed for mapping cells to bean properties. This method is called
164 * whenever {@link org.csveed.annotations.CsvFile#mappingStrategy()} is used. The default mapping strategy is
165 * {@link org.csveed.bean.ColumnIndexMapper}, which looks at either the position of a property within the class or
166 * the custom index if {@link org.csveed.annotations.CsvCell#columnIndex()} or
167 * {@link #mapColumnIndexToProperty(int, String)} has been set.
168 *
169 * @param mapper
170 * the mapping strategy to employ for mapping cells to bean properties
171 *
172 * @return convenience for chaining
173 */
174 BeanInstructions setMapper(Class<? extends AbstractMapper> mapper);
175
176 /**
177 * Determines what dateformat to apply to the cell value before storing it as a date. This method is called whenever
178 * {@link org.csveed.annotations.CsvDate} is used. The default for date format is dd-MM-yyyy.
179 *
180 * @param propertyName
181 * the name of the property to write the date to
182 * @param dateFormat
183 * the date format to apply for parsing the date value
184 *
185 * @return convenience for chaining
186 */
187 BeanInstructions setDate(String propertyName, String dateFormat);
188
189 /**
190 * Determines what Locale to apply to the cell value before converting it to a number. This method is called
191 * whenever {@link org.csveed.annotations.CsvLocalizedNumber} is used. The default for Locale is the Locale of the
192 * server.
193 *
194 * @param propertyName
195 * the name of the property to write the data to
196 * @param locale
197 * the Locale to apply for converting the number
198 *
199 * @return convenience for chaining
200 */
201 BeanInstructions setLocalizedNumber(String propertyName, Locale locale);
202
203 /**
204 * Determines if the field is required. If so, the cell may not be empty and a
205 * {@link org.csveed.report.CsvException} will be thrown if this occurs. This method is called whenever
206 * {@link org.csveed.annotations.CsvCell#required()} is used. The default for a property is false.
207 *
208 * @param propertyName
209 * property for which the requirement applies
210 * @param required
211 * whether the cell must be not-null
212 *
213 * @return convenience for chaining
214 */
215 BeanInstructions setRequired(String propertyName, boolean required);
216
217 /**
218 * Sets a custom {@link PropertyEditor} for the property. This PropertyEditor is called to convert the text to the
219 * type of the property and set it on the bean. This method is called whenever
220 * {@link org.csveed.annotations.CsvConverter#converter()} is used. The default for a property is based on the
221 * wonderful set of PropertyEditors that Spring offers, which is all basics and some extras as well.
222 *
223 * @param propertyName
224 * property to which the converter must be applied
225 * @param converter
226 * PropertyEditor to apply to the property
227 *
228 * @return convenience for chaining
229 */
230 BeanInstructions setConverter(String propertyName, Converter converter);
231
232 /**
233 * Sets a field to be ignored for purposes of mapping. This method is called whenever
234 * {@link org.csveed.annotations.CsvIgnore} is used. By default none of the fields are ignored unless, custom
235 * instructions are used. In this case, all fields are ignored by default.
236 *
237 * @param propertyName
238 * property which must be ignored for mapping
239 *
240 * @return convenience for chaining
241 */
242 BeanInstructions ignoreProperty(String propertyName);
243
244 /**
245 * Maps a column in the CSV to a specific property. This method is called whenever
246 * {@link org.csveed.annotations.CsvCell#columnIndex()} is used. By default there is NO mapping when custom
247 * instructions are used, so you should roll your own. Note that column indexes are 1-based, not 0-based
248 *
249 * @param columnIndex
250 * column index for which the property mapping must be applied
251 * @param propertyName
252 * property to which the index-based mapping must be applied
253 *
254 * @return convenience for chaining
255 */
256 BeanInstructions mapColumnIndexToProperty(int columnIndex, String propertyName);
257
258 /**
259 * Maps a column name (which is found in the header) to a specific property. Note that to use this, headers must be
260 * enabled. This method is called whenever {@link org.csveed.annotations.CsvCell#columnName()} is used. By default
261 * there is NO mapping when custom instructions are used, so you should roll your own. Also, don't forget to
262 * {@link #setMapper(Class)} to {@link org.csveed.bean.ColumnNameMapper} for this to work.
263 *
264 * @param columnName
265 * column name for which the property mapping must be applied
266 * @param propertyName
267 * property to which the name-based mapping must be applied
268 *
269 * @return convenience for chaining
270 */
271 BeanInstructions mapColumnNameToProperty(String columnName, String propertyName);
272
273 /**
274 * Determines what property will receive the header name in the currently active dynamic column.
275 *
276 * @param propertyName
277 * property in which the active dynamic header name must be stored
278 *
279 * @return convenience for chaining
280 */
281 BeanInstructions setHeaderNameToProperty(String propertyName);
282
283 /**
284 * Determines what property will receive the cell value in the currently active dynamic column.
285 *
286 * @param propertyName
287 * property in which the active dynamic column value must be stored
288 *
289 * @return convenience for chaining
290 */
291 BeanInstructions setHeaderValueToProperty(String propertyName);
292
293 /**
294 * Returns the class of the bean on which processing is taking place.
295 *
296 * @return class of the processed bean
297 */
298 Class getBeanClass();
299
300 /**
301 * Returns the properties of the bean on which processing is taking place.
302 *
303 * @return the properties of the processed bean
304 */
305 BeanProperties getProperties();
306
307 /**
308 * Returns the instructions for processing rows.
309 *
310 * @return the row instructions
311 */
312 RowInstructions getRowInstructions();
313
314 /**
315 * States whether a header is used.
316 *
317 * @return true if a header is used
318 */
319 boolean useHeader();
320
321 /**
322 * The first column that counts as a dynamic column.
323 *
324 * @return the first of the dynamic columns
325 */
326 Column getStartIndexDynamicColumns();
327
328 /**
329 * The mapping strategy to use for processing the bean.
330 *
331 * @return applied mapping strategy
332 */
333 Class<? extends AbstractMapper> getMappingStrategy();
334
335 /**
336 * Logs all the settings.
337 */
338 void logSettings();
339
340 }