View Javadoc
1   package com.opencsv.bean;
2   
3   /*
4    Copyright 2007 Kyle Miller.
5   
6    Licensed under the Apache License, Version 2.0 (the "License");
7    you may not use this file except in compliance with the License.
8    You may obtain a copy of the License at
9   
10   http://www.apache.org/licenses/LICENSE-2.0
11  
12   Unless required by applicable law or agreed to in writing, software
13   distributed under the License is distributed on an "AS IS" BASIS,
14   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   See the License for the specific language governing permissions and
16   limitations under the License.
17   */
18  
19  import com.opencsv.CSVReader;
20  import com.opencsv.exceptions.*;
21  import org.apache.commons.collections4.MultiValuedMap;
22  
23  import java.io.IOException;
24  import java.lang.reflect.Field;
25  import java.util.Locale;
26  
27  /**
28   * The interface for the classes that handle translating between the columns in
29   * the CSV file to an actual object.
30   * <p>Any implementing class <em>must</em> be thread-safe. Specifically, the
31   * following methods must be thread-safe:</p>
32   * <ul><li>{@link #populateNewBean(java.lang.String[])}</li>
33   * <li>{@link #transmuteBean(java.lang.Object)}</li></ul>
34   *
35   * @param <T> Type of object you are converting the data to.
36   */
37  public interface MappingStrategy<T> {
38  
39      /**
40       * Implementation of this method can grab the header line before parsing
41       * begins to use to map columns to bean properties.
42       *
43       * @param reader The CSVReader to use for header parsing
44       * @throws java.io.IOException If parsing fails
45       * @throws CsvRequiredFieldEmptyException If a field is required, but the
46       *   header or column position for the field is not present in the input
47       */
48      void captureHeader(CSVReader reader) throws IOException, CsvRequiredFieldEmptyException;
49     
50      /**
51       * Implementations of this method must return an array of column headers
52       * based on the contents of the mapping strategy.
53       * If no header can or should be generated, an array of zero length must
54       * be returned, and not {@code null}.
55       * @param bean One fully populated bean from which the header can be derived.
56       *   This is important in the face of joining and splitting. If we have a
57       *   MultiValuedMap as a field that is the target for a join on reading, that
58       *   same field must be split into multiple columns on writing. Since the
59       *   joining is done via regular expressions, it is impossible for opencsv
60       *   to know what the column names are supposed to be on writing unless this
61       *   bean includes a fully populated map.
62       * @return An array of column names for a header. This may be an empty array
63       *   if no header should be written, but it must not be {@code null}.
64       * @throws CsvRequiredFieldEmptyException If a required header is missing
65       *   while attempting to write. Since every other header is hard-wired
66       *   through the bean fields and their associated annotations, this can only
67       *   happen with multi-valued fields.
68       * @since 3.9
69       */
70      String[] generateHeader(T bean) throws CsvRequiredFieldEmptyException;
71  
72      /**
73       * Determines whether the mapping strategy is driven by annotations.
74       *
75       * @return Whether the mapping strategy is driven by annotations
76       * @deprecated This is simply no longer necessary.
77       */
78      @Deprecated
79      default boolean isAnnotationDriven() {return false;}
80      
81      /**
82       * Takes a line of input from a CSV file and creates a bean out of it.
83       * 
84       * @param line A line of input returned from {@link com.opencsv.CSVReader}
85       * @return A bean containing the converted information from the input
86       * @throws CsvBeanIntrospectionException Generally, if some part of the bean cannot
87       *   be accessed and used as needed
88       * @throws CsvFieldAssignmentException A more specific subclass of this
89       *   exception is thrown for any problem decoding and assigning a field
90       *   of the input to a bean field
91       * @throws CsvChainedException If multiple exceptions are thrown for the
92       * same input line
93       * @since 4.2
94       */
95      T populateNewBean(String[] line)
96              throws CsvBeanIntrospectionException, CsvFieldAssignmentException,
97              CsvChainedException;
98      
99      /**
100      * Sets the locale for all error messages.
101      * The default implementation does nothing, as it is expected that most
102      * implementations of this interface will not support multiple languages.
103      *
104      * @param errorLocale Locale for error messages. If null, the default locale
105      *   is used.
106      * @since 4.0
107      */
108     default void setErrorLocale(Locale errorLocale) {}
109    
110     /**
111      * Sets the class type that is being mapped.
112      * May perform additional initialization tasks. If instantiating a
113      * mapping strategy, this method should be called after any other
114      * initialization, for example a call to
115      * {@link #setErrorLocale(Locale)} or {@link #setProfile(String)}.
116      *
117      * @param type Class type.
118      * @throws CsvBadConverterException If a field in the bean is annotated
119      *   with a custom converter that cannot be initialized. If you are not
120      *   using custom converters that you have written yourself, it should be
121      *   safe to catch this exception and ignore it.
122      */
123     void setType(Class<? extends T> type) throws CsvBadConverterException;
124 
125     /**
126      * Sets the profile this mapping strategy will use when configuring bean
127      * fields.
128      * <p>The default implementation throws
129      * {@link UnsupportedOperationException}.</p>
130      *
131      * @param profile The profile to use
132      * @since 5.4
133      */
134     default void setProfile(String profile) {
135         throw new UnsupportedOperationException();
136     }
137 
138     /**
139      * <p>
140      *     When processing a bean for reading or writing, ignore the given fields
141      * from the given classes completely, including all annotations and
142      * requirements.
143      * This method has two compelling applications:</p>
144      * <ol>
145      *     <li>If you are not able to modify the source code of the beans you
146      *     use, or</li>
147      *     <li>If you use a mapping strategy without annotations and want to
148      *     exclude a small number of fields from a bean with a large number of
149      *     fields.</li>
150      * </ol>
151      * <p>Calling this method overwrites the fields passed in from any previous
152      * calls. It is legal to call this method before calling
153      * {@link #setType(Class)}, and it may be more efficient to do so.</p>
154      * <p>Caution must be exercised with this method when letting opencsv
155      * automatically determine the mapping strategy. When a field is ignored,
156      * opencsv pretends it does not exist at all. If, for instance, all fields
157      * annotated with opencsv binding annotations are ignored, opencsv will
158      * automatically switch to {@link HeaderColumnNameMappingStrategy} and
159      * assume header names exactly match field names.</p>
160      * <p>An implementation of this interface is not required to implement this
161      * method. The default implementation throws
162      * {@link UnsupportedOperationException}.</p>
163      * @param fields All fields to be ignored, mapped from the classes of which
164      *               they are members. These are the classes as opencsv
165      *               encounters them, not necessarily the declaring classes if
166      *               any fields are inherited. May be {@code null}.
167      * @throws IllegalArgumentException If any entry in the map has a
168      * {@code null} key, a {@code null} value, or if the value is not a field
169      * in the class represented by the key
170      * @since 5.0
171      * @see CsvIgnore
172      */
173     default void ignoreFields(MultiValuedMap<Class<?>, Field> fields) throws IllegalArgumentException {
174         throw new UnsupportedOperationException();
175     }
176    
177     /**
178      * Transmutes a bean instance into an array of {@link String}s to be written
179      * to a CSV file.
180      * 
181      * @param bean The bean to be transmuted
182      * @return The converted values of the bean fields in the correct order,
183      *   ready to be passed to a {@link com.opencsv.CSVWriter}
184      * @throws CsvFieldAssignmentException A more specific subclass of this
185      *   exception is thrown for any problem decoding and assigning a field
186      *   of the input to a bean field
187      * @throws CsvChainedException If multiple exceptions are thrown for the
188      * same input line
189      */
190     String[] transmuteBean(T bean) throws CsvFieldAssignmentException, CsvChainedException;
191 }