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.regex.Matcher;
20  
21  import org.apache.commons.collections4.MultiValuedMap;
22  
23  /**
24   * Joins the values of multiple columns from the input into one bean field based
25   * on a pattern for the column names.
26   * 
27   * @author Andrew Rucker Jones
28   * @since 4.2
29   */
30  @Documented
31  @Retention(RetentionPolicy.RUNTIME)
32  @Target(ElementType.FIELD)
33  @Repeatable(CsvBindAndJoinByNames.class)
34  public @interface CsvBindAndJoinByName {
35  
36      /**
37       * Whether or not the annotated field is required to be present in every
38       * data set of the input.
39       * This means that the input cannot be empty. The output after conversion is
40       * not guaranteed to be non-empty. "Input" means the string from every
41       * matching field in the CSV file on reading and the bean member variable on
42       * writing.
43       *
44       * @return If the field is required to contain information.
45       */
46      boolean required() default false;
47  
48      /**
49       * A regular expression defining which column names are to be included in
50       * this bean field.
51       * If not specified, the name of the column must be identical to the name
52       * of the field(s). Since this annotation can combine multiple columns from
53       * the input, and they are allowed to have the same name, it is legitimate
54       * to let opencsv default to using the field name even with this annotation.
55       *
56       * @return The name of the column(s) in the CSV file from which this field
57       * should be taken.
58       */
59      String column() default "";
60  
61      /**
62       * Defines the locale to be used for decoding the argument.
63       * <p>If not specified, the current default locale is used. The locale must be
64       * one recognized by {@link java.util.Locale}. Locale conversion is supported
65       * for the following data types:<ul>
66       * <li>byte and {@link java.lang.Byte}</li>
67       * <li>float and {@link java.lang.Float}</li>
68       * <li>double and {@link java.lang.Double}</li>
69       * <li>int and {@link java.lang.Integer}</li>
70       * <li>long and {@link java.lang.Long}</li>
71       * <li>short and {@link java.lang.Short}</li>
72       * <li>{@link java.math.BigDecimal}</li>
73       * <li>{@link java.math.BigInteger}</li>
74       * <li>All time data types supported by {@link com.opencsv.bean.CsvDate}</li></ul>
75       * <p>The locale must be in a format accepted by
76       * {@link java.util.Locale#forLanguageTag(java.lang.String)}</p>
77       * <p>Caution must be exercised with the default locale, for the default
78       * locale for numerical types does not mean the locale of the running
79       * program, such as en-US or de-DE, but rather <em>no</em> locale. Numbers
80       * will be parsed more or less the way the Java compiler would parse them.
81       * That means, for instance, that thousands separators in long numbers are
82       * not permitted, even if the locale of the running program would accept
83       * them. When dealing with locale-sensitive data, it is always best to
84       * specify the locale explicitly.</p>
85       *
86       * @return The locale selected. The default is indicated by an empty string.
87       */
88      String locale() default "";
89  
90      /**
91       * Whether or not the same locale is used for writing as for reading.
92       * If this is true, {@link #locale()} is used for both reading and writing
93       * and {@link #writeLocale()} is ignored.
94       *
95       * @return Whether the read locale is used for writing as well
96       * @since 5.0
97       */
98      boolean writeLocaleEqualsReadLocale() default true;
99  
100     /**
101      * The locale for writing.
102      * This field is ignored unless {@link #writeLocaleEqualsReadLocale()} is
103      * {@code false}. The format is identical to {@link #locale()}.
104      *
105      * @return The locale for writing, if one is in use
106      * @see #locale()
107      * @see #writeLocaleEqualsReadLocale()
108      * @since 5.0
109      */
110     String writeLocale() default "";
111 
112     /**
113      * Defines the class used for the multi-valued map.
114      * <p>This must be a specific implementation of
115      * {@link org.apache.commons.collections4.MultiValuedMap}, and not an
116      * interface! The default is set to {@code MultiValuedMap.class} as a signal
117      * to use the default for the interface supplied in the bean to be
118      * populated.</p>
119      * <p>The logic for determining which class to instantiate for the
120      * multi-valued map is as follows. In all cases, the implementation must
121      * have a nullary constructor.</p>
122      * <ol><li>If the bean declares a specific implementation instead of the
123      * associated interface
124      * (e.g. {@link org.apache.commons.collections4.multimap.ArrayListValuedHashMap}
125      * vs.
126      * {@link org.apache.commons.collections4.ListValuedMap}), that specific
127      * implementation will always be used.</li>
128      * <li>Otherwise, the implementation named in this field will be used, if it
129      * is not an interface.</li>
130      * <li>If no implementation is specified in this field (i.e. if
131      * an interface is specified, as is the default), a default is used
132      * based on the interface of the bean field annotated. These are:
133      * <ul><li>{@link org.apache.commons.collections4.multimap.ArrayListValuedHashMap} for {@link org.apache.commons.collections4.MultiValuedMap}</li>
134      * <li>{@link org.apache.commons.collections4.multimap.ArrayListValuedHashMap} for {@link org.apache.commons.collections4.ListValuedMap}</li>
135      * <li>{@link org.apache.commons.collections4.multimap.HashSetValuedHashMap} for {@link org.apache.commons.collections4.SetValuedMap}</li></ul></li></ol>
136      * 
137      * @return A class implementing {@link org.apache.commons.collections4.MultiValuedMap}
138      */
139     Class<? extends MultiValuedMap> mapType() default MultiValuedMap.class;
140     
141     /**
142      * Defines what type the elements of the map should have.
143      * It is necessary to instantiate elements of the map, and it is not
144      * always possible to determine the type of the elements at runtime.
145      * A perfect example of this is {@code Map<String, ? extends Number>}.
146      * 
147      * @return The type of the map elements
148      */
149     Class<?> elementType();
150 
151     /**
152      * Once the data points have been recovered from the various columns of the
153      * input, a custom converter can optionally be specified for conversion of
154      * each of the data points before they are joined in a
155      * {@link org.apache.commons.collections4.MultiValuedMap}.
156      *
157      * @return The converter applied to each of the data points extracted from
158      * the input
159      * @since 4.3
160      */
161     Class<? extends AbstractCsvConverter> converter() default AbstractCsvConverter.class;
162 
163     /**
164      * If this is anything but an empty string, it will be used as a regular
165      * expression to extract part of the input before conversion to the bean
166      * field.
167      * <p>An empty string behaves as if the regular expression {@code ^(.*)$}
168      * had been specified.</p>
169      * <p>The regular expression will be compiled and every field of input will
170      * be passed through it, naturally after the input has been normalized
171      * (quotations and escape characters removed). The first capture group will
172      * be extracted, and that string will be passed on to the appropriate
173      * conversion routine for the bean field in question.</p>
174      * <p>This makes it possible to easily convert input fields with forms like
175      * {@code Grade: 94.2} into {@code 94.2}, which can then be converted to a
176      * floating point bean field, all without writing a custom converter.</p>
177      * <p>The regular expression is applied to the entire string in question
178      * (i.e. with {@link Matcher#matches()}), instead of just the beginning of
179      * the string ({@link Matcher#lookingAt()}) or anywhere in the string
180      * ({@link Matcher#find()}). If it fails to match, the input string is
181      * passed unchanged to the appropriate conversion routine for the bean
182      * field. The reason for this is two-fold:</p>
183      * <ol><li>The matching may occur against an empty string. If the field is
184      * not required, this is legitimate, but it's likely the regular expression
185      * is not written to accommodate this possibility, and it may indeed not be
186      * at all desirable to.</li>
187      * <li>If there is an error in either the regular expression or the input
188      * that causes the match to fail, there is a good likelihood that the
189      * subsequent conversion will fail with a
190      * {@link com.opencsv.exceptions.CsvDataTypeMismatchException} if the
191      * input is not being converted into a simple string.</li></ol>
192      * <p>This is the inverse operation of {@link #format()}.</p>
193      *
194      * @return A regular expression, the first capture group of which will be
195      * used for conversion to the bean field
196      * @since 4.3
197      */
198     String capture() default "";
199 
200     /**
201      * If this is anything but an empty string, it will be used as a format
202      * string for {@link java.lang.String#format(String, Object...)} on
203      * writing.
204      * <p>An empty string behaves as if the format string {@code "%s"} had been
205      * specified.</p>
206      * <p>The format string, if it is not empty, should contain one and only
207      * one {@code %s}, which will be replaced by the string value of the bean
208      * field after conversion. If, however, the bean field is empty, then the
209      * output will be empty as well, as opposed to passing an empty string to
210      * this format string and using that as the output.</p>
211      * <p>This is the inverse operation of {@link #capture()}.</p>
212      *
213      * @return A format string for writing fields
214      * @since 4.3
215      */
216     String format() default "";
217 
218     /**
219      * A profile can be used to annotate the same field differently for
220      * different inputs or outputs.
221      * <p>Perhaps you have multiple input sources, and they all use different
222      * header names or positions for the same data. With profiles, you don't
223      * have to create different beans with the same fields and different
224      * annotations for each input. Simply annotate the same field multiple
225      * times and specify the profile when you parse the input.</p>
226      * <p>The same applies to output: if you want to be able to represent the
227      * same data in multiple CSV formats (that is, with different headers or
228      * orders), annotate the bean fields multiple times with different profiles
229      * and specify which profile you want to use on writing.</p>
230      * <p>Results are undefined if profile names are not unique.</p>
231      * <p>If the same configuration applies to multiple profiles, simply list
232      * all applicable profile names here. This parameter is an array of
233      * strings.</p>
234      * <p>The empty string, which is the default value, specifies the default
235      * profile and will be used if no annotation for the specific profile
236      * being used can be found, or if no profile is specified.</p>
237      *
238      * @return The names of the profiles this configuration is for
239      * @since 5.4
240      */
241     String[] profiles() default "";
242 }