View Javadoc
1   /*
2    * Copyright 2017 Andrew Rucker Jones.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package com.opencsv.bean;
17  
18  import java.lang.annotation.*;
19  import java.util.Collection;
20  import java.util.regex.Matcher;
21  
22  /**
23   * This annotation interprets one field of the input as a collection that will
24   * be split up into its components and assigned to a collection-based bean field.
25   * 
26   * @author Andrew Rucker Jones
27   * @since 4.2
28   */
29  @Documented
30  @Retention(RetentionPolicy.RUNTIME)
31  @Target(ElementType.FIELD)
32  @Repeatable(CsvBindAndSplitByPositions.class)
33  public @interface CsvBindAndSplitByPosition {
34  
35      /**
36       * Whether or not the annotated field is required to be present in every
37       * data set of the input.
38       * This means that the input cannot be empty. The output after conversion is
39       * not guaranteed to be non-empty. "Input" means the string from the field
40       * in the CSV file on reading and the bean member variable on writing.
41       *
42       * @return If the field is required to contain information.
43       */
44      boolean required() default false;
45  
46      /**
47       * The column position in the input that is used to fill the annotated
48       * field.
49       *
50       * @return The position of the column in the CSV file from which this field
51       * should be taken. This column number is zero-based.
52       */
53      int position();
54  
55      /**
56       * Defines the locale to be used for decoding the argument.
57       * <p>If not specified, the current default locale is used. The locale must be
58       * one recognized by {@link java.util.Locale}. Locale conversion is supported
59       * for the following data types:<ul>
60       * <li>byte and {@link java.lang.Byte}</li>
61       * <li>float and {@link java.lang.Float}</li>
62       * <li>double and {@link java.lang.Double}</li>
63       * <li>int and {@link java.lang.Integer}</li>
64       * <li>long and {@link java.lang.Long}</li>
65       * <li>short and {@link java.lang.Short}</li>
66       * <li>{@link java.math.BigDecimal}</li>
67       * <li>{@link java.math.BigInteger}</li>
68       * <li>All time data types supported by {@link com.opencsv.bean.CsvDate}</li></ul>
69       * <p>The locale must be in a format accepted by
70       * {@link java.util.Locale#forLanguageTag(java.lang.String)}</p>
71       * <p>Caution must be exercised with the default locale, for the default
72       * locale for numerical types does not mean the locale of the running
73       * program, such as en-US or de-DE, but rather <em>no</em> locale. Numbers
74       * will be parsed more or less the way the Java compiler would parse them.
75       * That means, for instance, that thousands separators in long numbers are
76       * not permitted, even if the locale of the running program would accept
77       * them. When dealing with locale-sensitive data, it is always best to
78       * specify the locale explicitly.</p>
79       *
80       * @return The locale selected. The default is indicated by an empty string.
81       */
82      String locale() default "";
83  
84      /**
85       * Whether or not the same locale is used for writing as for reading.
86       * If this is true, {@link #locale()} is used for both reading and writing
87       * and {@link #writeLocale()} is ignored.
88       *
89       * @return Whether the read locale is used for writing as well
90       * @since 5.0
91       */
92      boolean writeLocaleEqualsReadLocale() default true;
93  
94      /**
95       * The locale for writing.
96       * This field is ignored unless {@link #writeLocaleEqualsReadLocale()} is
97       * {@code false}. The format is identical to {@link #locale()}.
98       *
99       * @return The locale for writing, if one is in use
100      * @see #locale()
101      * @see #writeLocaleEqualsReadLocale()
102      * @since 5.0
103      */
104     String writeLocale() default "";
105 
106     /**
107      * Defines a regular expression for splitting the input.
108      * The input string is split using the value of this attribute and the
109      * result is put into a collection. The default splits on whitespace.
110      * 
111      * @return The regular expression used for splitting the input
112      */
113     String splitOn() default "\\s+";
114     
115     /**
116      * When writing a collection from a bean, this string will be used to
117      * separate elements of the collection.
118      * Defaults to one space.
119      * 
120      * @return Delimiter between elements for writing a collection
121      */
122     String writeDelimiter() default " ";
123     
124     /**
125      * Defines the class used for the collection.
126      * <p>This must be a specific implementation of a collection, and not an
127      * interface! The default is set to {@code Collection.class} as a signal to
128      * use the default for the interface supplied in the bean to be populated.</p>
129      * <p>The logic for determining which class to instantiate for the
130      * collection is as follows. In all cases, the implementation must have a
131      * nullary constructor.</p>
132      * <ol><li>If the bean declares a specific implementation instead of the
133      * associated interface (e.g. {@link java.util.ArrayList} vs.
134      * {@link java.util.List}), that specific implementation will always be
135      * used.</li>
136      * <li>Otherwise, the implementation named in this field will be used, if it
137      * is not an interface.</li>
138      * <li>If no implementation is specified in this field (i.e. if
139      * an interface is specified, as is the default), a default is used
140      * based on the interface of the bean field annotated. These are:
141      * <ul><li>{@link java.util.ArrayList} for {@link java.util.Collection}</li>
142      * <li>{@link java.util.ArrayList} for {@link java.util.List}</li>
143      * <li>{@link java.util.HashSet} for {@link java.util.Set} unless
144      * {@link #elementType()} is an enumeration type, in which case
145      * {@link java.util.EnumSet} is used</li>
146      * <li>{@link java.util.TreeSet} for {@link java.util.SortedSet}</li>
147      * <li>{@link java.util.TreeSet} for {@link java.util.NavigableSet}</li>
148      * <li>{@link java.util.ArrayDeque} for {@link java.util.Queue}</li>
149      * <li>{@link java.util.ArrayDeque} for {@link java.util.Deque}</li>
150      * <li>{@link org.apache.commons.collections4.bag.HashBag} for {@link org.apache.commons.collections4.Bag}</li>
151      * <li>{@link org.apache.commons.collections4.bag.TreeBag} for {@link org.apache.commons.collections4.SortedBag}</ul></li></ol>
152      * 
153      * @return A class implementing {@link java.util.Collection}
154      */
155     Class<? extends Collection> collectionType() default Collection.class;
156     
157     /**
158      * Defines what type the elements of the collection should have.
159      * It is necessary to instantiate elements of the collection, and it is not
160      * always possible to determine the type of the given collection at runtime.
161      * A perfect example of this is {@code List<? extends Number>}.
162      * 
163      * @return The type of the collection elements
164      */
165     Class<?> elementType();
166 
167     /**
168      * Once the input has been split, a custom converter can optionally be
169      * specified for conversion of each of the data points.
170      *
171      * @return The converter applied to each of the data points extracted from
172      * the input
173      * @since 4.3
174      */
175     Class<? extends AbstractCsvConverter> converter() default AbstractCsvConverter.class;
176 
177     /**
178      * If this is anything but an empty string, it will be used as a regular
179      * expression to extract part of the input before conversion to the bean
180      * field.
181      * <p>An empty string behaves as if the regular expression {@code ^(.*)$}
182      * had been specified.</p>
183      * <p>The regular expression will be compiled and every field of input will
184      * be passed through it, naturally after the input has been normalized
185      * (quotations and escape characters removed). The first capture group will
186      * be extracted, and that string will be passed on to the appropriate
187      * conversion routine for the bean field in question.</p>
188      * <p>This makes it possible to easily convert input fields with forms like
189      * {@code Grade: 94.2} into {@code 94.2}, which can then be converted to a
190      * floating point bean field, all without writing a custom converter.</p>
191      * <p>In the case of splitting the input, which is what this annotation
192      * does, the input will be split <em>before</em> this regular expression is
193      * then applied to every element of the list resulting from splitting the
194      * input. This regular expression is <em>not</em> applied to the entire
195      * input field before splitting.</p>
196      * <p>The regular expression is applied to the entire string in question
197      * (i.e. with {@link Matcher#matches()}), instead of just the beginning of
198      * the string ({@link Matcher#lookingAt()}) or anywhere in the string
199      * ({@link Matcher#find()}). If it fails to match, the input string is
200      * passed unchanged to the appropriate conversion routine for the bean
201      * field. The reason for this is two-fold:</p>
202      * <ol><li>The matching may occur against an empty string. If the field is
203      * not required, this is legitimate, but it's likely the regular expression
204      * is not written to accommodate this possibility, and it may indeed not be
205      * at all desirable to.</li>
206      * <li>If there is an error in either the regular expression or the input
207      * that causes the match to fail, there is a good likelihood that the
208      * subsequent conversion will fail with a
209      * {@link com.opencsv.exceptions.CsvDataTypeMismatchException} if the
210      * input is not being converted into a simple string.</li></ol>
211      * <p>This is the inverse operation of {@link #format()}.</p>
212      *
213      * @return A regular expression, the first capture group of which will be
214      * used for conversion to the bean field
215      * @since 4.3
216      */
217     String capture() default "";
218 
219     /**
220      * If this is anything but an empty string, it will be used as a format
221      * string for {@link java.lang.String#format(String, Object...)} on
222      * writing.
223      * <p>An empty string behaves as if the format string {@code "%s"} had been
224      * specified.</p>
225      * <p>The format string, if it is not empty, should contain one and only
226      * one {@code %s}, which will be replaced by the string value of the bean
227      * field after conversion. If, however, the bean field is empty, then the
228      * output will be empty as well, as opposed to passing an empty string to
229      * this format string and using that as the output.</p>
230      * <p>This formatting will be applied to every element of the input
231      * collection separately before writing.</p>
232      * <p>This is the inverse operation of {@link #capture()}.</p>
233      *
234      * @return A format string for writing fields
235      * @since 4.3
236      */
237     String format() default "";
238 
239     /**
240      * A profile can be used to annotate the same field differently for
241      * different inputs or outputs.
242      * <p>Perhaps you have multiple input sources, and they all use different
243      * header names or positions for the same data. With profiles, you don't
244      * have to create different beans with the same fields and different
245      * annotations for each input. Simply annotate the same field multiple
246      * times and specify the profile when you parse the input.</p>
247      * <p>The same applies to output: if you want to be able to represent the
248      * same data in multiple CSV formats (that is, with different headers or
249      * orders), annotate the bean fields multiple times with different profiles
250      * and specify which profile you want to use on writing.</p>
251      * <p>Results are undefined if profile names are not unique.</p>
252      * <p>If the same configuration applies to multiple profiles, simply list
253      * all applicable profile names here. This parameter is an array of
254      * strings.</p>
255      * <p>The empty string, which is the default value, specifies the default
256      * profile and will be used if no annotation for the specific profile
257      * being used can be found, or if no profile is specified.</p>
258      *
259      * @return The names of the profiles this configuration is for
260      * @since 5.4
261      */
262     String[] profiles() default "";
263 }