/*
 * Copyright 2016 Andrew Rucker Jones.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.opencsv.bean;

import com.opencsv.*;
import com.opencsv.enums.CSVReaderNullFieldIndicator;
import org.apache.commons.collections4.ListValuedMap;
import org.apache.commons.collections4.MultiValuedMap;
import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
import org.apache.commons.lang3.ObjectUtils;

import java.io.Reader;
import java.lang.reflect.Field;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;

This class makes it possible to bypass all the intermediate steps and classes in setting up to read from a CSV source to a list of beans.

This is the place to start if you're reading a CSV source into beans, especially if you're binding the input's columns to the bean's variables using the annotations CsvBindByName, CsvCustomBindByName, CsvBindByPosition, or CsvCustomBindByPosition.

If you want nothing but defaults for the entire import, your code can look as simple as this, where myreader is any valid Reader:
List<MyBean> result = new CsvToBeanBuilder(myreader).withType(MyBean.class).build().parse();

This builder is intelligent enough to guess the mapping strategy according to the following strategy:

  1. If a mapping strategy is explicitly set, it is always used.
  2. If CsvBindByPosition or CsvCustomBindByPosition is present, ColumnPositionMappingStrategy is used.
  3. Otherwise, HeaderColumnNameMappingStrategy is used. This includes the case when CsvBindByName or CsvCustomBindByName are being used. The annotations will automatically be recognized.
Author:Andrew Rucker Jones
Type parameters:
  • <T> – Type of the bean to be populated
Since:3.9
/** * This class makes it possible to bypass all the intermediate steps and classes * in setting up to read from a CSV source to a list of beans. * <p>This is the place to start if you're reading a CSV source into beans, * especially if you're binding the input's columns to the bean's variables * using the annotations {@link CsvBindByName}, {@link CsvCustomBindByName}, * {@link CsvBindByPosition}, or {@link CsvCustomBindByPosition}.</p> * <p>If you want nothing but defaults for the entire import, your code can look * as simple as this, where {@code myreader} is any valid {@link java.io.Reader Reader}:<br> * {@code List<MyBean> result = new CsvToBeanBuilder(myreader).withType(MyBean.class).build().parse();}</p> * <p>This builder is intelligent enough to guess the mapping strategy according to the * following strategy:</p><ol> * <li>If a mapping strategy is explicitly set, it is always used.</li> * <li>If {@link CsvBindByPosition} or {@link CsvCustomBindByPosition} is present, * {@link ColumnPositionMappingStrategy} is used.</li> * <li>Otherwise, {@link HeaderColumnNameMappingStrategy} is used. This includes * the case when {@link CsvBindByName} or {@link CsvCustomBindByName} are being * used. The annotations will automatically be recognized.</li></ol> * * @param <T> Type of the bean to be populated * @author Andrew Rucker Jones * @since 3.9 */
public class CsvToBeanBuilder<T> {
See Also:
  • CsvToBean.mappingStrategy
/** @see CsvToBean#mappingStrategy */
private MappingStrategy<? extends T> mappingStrategy = null;
A CSVReader will be built out of this Reader.
See Also:
  • CsvToBean.csvReader
/** * A CSVReader will be built out of this {@link java.io.Reader}. * @see CsvToBean#csvReader */
private final Reader reader;
Allow the user to pass in a prebuilt/custom CSVReader.
/** * Allow the user to pass in a prebuilt/custom {@link com.opencsv.CSVReader}. */
private final CSVReader csvReader;
See Also:
  • CsvToBean.filter
/** @see CsvToBean#filter */
private CsvToBeanFilter filter = null;
See Also:
  • CsvToBean.throwExceptions
/** @see CsvToBean#throwExceptions */
private boolean throwExceptions = true;
See Also:
/** @see com.opencsv.CSVParser#nullFieldIndicator */
private CSVReaderNullFieldIndicator nullFieldIndicator = null;
See Also:
  • CSVReader.keepCR
/** @see com.opencsv.CSVReader#keepCR */
private boolean keepCR;
See Also:
  • CSVReader.skipLines
/** @see com.opencsv.CSVReader#skipLines */
private Integer skipLines = null;
See Also:
/** @see com.opencsv.CSVReader#verifyReader */
private Boolean verifyReader = null;
See Also:
  • CSVParser.separator
/** @see com.opencsv.CSVParser#separator */
private Character separator = null;
See Also:
  • CSVParser.quotechar
/** @see com.opencsv.CSVParser#quotechar */
private Character quoteChar = null;
See Also:
  • CSVParser.escape
/** @see com.opencsv.CSVParser#escape */
private Character escapeChar = null;
See Also:
  • CSVParser.strictQuotes
/** @see com.opencsv.CSVParser#strictQuotes */
private Boolean strictQuotes = null;
See Also:
  • CSVParser.ignoreLeadingWhiteSpace
/** @see com.opencsv.CSVParser#ignoreLeadingWhiteSpace */
private Boolean ignoreLeadingWhiteSpace = null;
See Also:
  • CSVParser.ignoreQuotations
/** @see com.opencsv.CSVParser#ignoreQuotations */
private Boolean ignoreQuotations = null;
See Also:
  • type.type
/** * @see HeaderColumnNameMappingStrategy#type */
private Class<? extends T> type = null;
See Also:
  • multilineLimit.multilineLimit
/** * @see com.opencsv.CSVReader#multilineLimit */
private Integer multilineLimit = null;
See Also:
  • orderedResults.orderedResults
/** * @see com.opencsv.bean.CsvToBean#orderedResults */
private boolean orderedResults = true;
See Also:
  • ignoreEmptyLines.ignoreEmptyLines
/** * @see com.opencsv.bean.CsvToBean#ignoreEmptyLines */
private boolean ignoreEmptyLines = false;
See Also:
  • errorLocale.errorLocale
/** * @see com.opencsv.bean.CsvToBean#errorLocale */
private Locale errorLocale = Locale.getDefault();
See Also:
  • verifiers.verifiers
/** * @see com.opencsv.bean.CsvToBean#verifiers */
private final List<BeanVerifier<T>> verifiers = new LinkedList<>();
See Also:
  • ignoredFields.ignoredFields
/** * @see com.opencsv.bean.AbstractMappingStrategy#ignoredFields */
private final ListValuedMap<Class<?>, Field> ignoredFields = new ArrayListValuedHashMap<>();
Constructor with the one parameter that is most definitely mandatory, and always will be.
Params:
  • reader – The reader that is the source of data for the CSV import
/** * Constructor with the one parameter that is most definitely mandatory, and * always will be. * @param reader The reader that is the source of data for the CSV import */
public CsvToBeanBuilder(Reader reader) { if(reader == null) { throw new IllegalArgumentException(ResourceBundle .getBundle(ICSVParser.DEFAULT_BUNDLE_NAME) // Must be default locale, because we don't have anything else yet .getString("reader.null")); } this.reader = reader; this.csvReader = null; }
Constructor with the one parameter that is most definitely mandatory, and always will be.
Params:
  • csvReader – The CSVReader that is the source of data for the CSV import
/** * Constructor with the one parameter that is most definitely mandatory, and * always will be. * * @param csvReader The CSVReader that is the source of data for the CSV import */
public CsvToBeanBuilder(CSVReader csvReader) { if (csvReader == null) { throw new IllegalArgumentException(ResourceBundle .getBundle(ICSVParser.DEFAULT_BUNDLE_NAME) // Must be default locale, because we don't have anything else yet .getString("reader.null")); } this.reader = null; this.csvReader = csvReader; }
Builds the CsvToBean out of the provided information.
Throws:
  • IllegalStateException – If a necessary parameter was not specified. Currently this means that both the mapping strategy and the bean type are not set, so it is impossible to determine a mapping strategy.
Returns:A valid CsvToBean
/** * Builds the {@link CsvToBean} out of the provided information. * @return A valid {@link CsvToBean} * @throws IllegalStateException If a necessary parameter was not specified. * Currently this means that both the mapping strategy and the bean type * are not set, so it is impossible to determine a mapping strategy. */
public CsvToBean<T> build() throws IllegalStateException { // Check for errors in the configuration first if(mappingStrategy == null && type == null) { throw new IllegalStateException(ResourceBundle.getBundle(ICSVParser.DEFAULT_BUNDLE_NAME, errorLocale).getString("strategy.type.missing")); } // Build Parser and Reader CsvToBean<T> bean = new CsvToBean<>(); if (csvReader != null) { bean.setCsvReader(csvReader); } else { CSVParser parser = buildParser(); bean.setCsvReader(buildReader(parser)); } // Set variables in CsvToBean itself bean.setThrowExceptions(throwExceptions); bean.setOrderedResults(orderedResults); if(filter != null) { bean.setFilter(filter); } bean.setVerifiers(verifiers); // Now find the mapping strategy and ignore irrelevant fields. // It's possible the mapping strategy has already been primed, so only // pass on our data if the user actually gave us something. if(mappingStrategy == null) { mappingStrategy = OpencsvUtils.determineMappingStrategy(type, errorLocale); } if(!ignoredFields.isEmpty()) { mappingStrategy.ignoreFields(ignoredFields); } bean.setMappingStrategy(mappingStrategy); // The error locale comes at the end so it can be propagated through all // of the components of CsvToBean, rendering the error locale homogeneous. bean.setErrorLocale(errorLocale); bean.setIgnoreEmptyLines(ignoreEmptyLines); return bean; }
Builds a CSVParser from the information provided to this builder. This is an intermediate step in building the CsvToBean.
Returns:An appropriate CSVParser
/** * Builds a {@link CSVParser} from the information provided to this builder. * This is an intermediate step in building the {@link CsvToBean}. * @return An appropriate {@link CSVParser} */
private CSVParser buildParser() { CSVParserBuilder csvpb = new CSVParserBuilder(); if(nullFieldIndicator != null) { csvpb.withFieldAsNull(nullFieldIndicator); } if(separator != null) { csvpb.withSeparator(separator); } if(quoteChar != null) { csvpb.withQuoteChar(quoteChar); } if(escapeChar != null) { csvpb.withEscapeChar(escapeChar); } if(strictQuotes != null) { csvpb.withStrictQuotes(strictQuotes); } if(ignoreLeadingWhiteSpace != null) { csvpb.withIgnoreLeadingWhiteSpace(ignoreLeadingWhiteSpace); } if(ignoreQuotations != null) { csvpb.withIgnoreQuotations(ignoreQuotations); } csvpb.withErrorLocale(errorLocale); return csvpb.build(); }
Builds a CSVReader from the information provided to this builder. This is an intermediate step in building the CsvToBean.
Params:
  • parser – The CSVParser necessary for this reader
Returns:An appropriate CSVReader
/** * Builds a {@link CSVReader} from the information provided to this builder. * This is an intermediate step in building the {@link CsvToBean}. * @param parser The {@link CSVParser} necessary for this reader * @return An appropriate {@link CSVReader} */
private CSVReader buildReader(CSVParser parser) { CSVReaderBuilder csvrb = new CSVReaderBuilder(reader); csvrb.withCSVParser(parser); csvrb.withKeepCarriageReturn(keepCR); if(verifyReader != null) { csvrb.withVerifyReader(verifyReader); } if(skipLines != null) { csvrb.withSkipLines(skipLines); } if(multilineLimit != null) { csvrb.withMultilineLimit(multilineLimit); } csvrb.withErrorLocale(errorLocale); return csvrb.build(); }
Params:
  • mappingStrategy – Please see the "See Also" section
See Also:
  • setMappingStrategy.setMappingStrategy(MappingStrategy)
Returns:this
/** * @see CsvToBean#setMappingStrategy(com.opencsv.bean.MappingStrategy) * @param mappingStrategy Please see the "See Also" section * @return {@code this} */
public CsvToBeanBuilder<T> withMappingStrategy(MappingStrategy<? extends T> mappingStrategy) { this.mappingStrategy = mappingStrategy; return this; }
Params:
  • filter – Please see the "See Also" section
See Also:
  • setFilter.setFilter(CsvToBeanFilter)
Returns:this
/** * @see CsvToBean#setFilter(com.opencsv.bean.CsvToBeanFilter) * @param filter Please see the "See Also" section * @return {@code this} */
public CsvToBeanBuilder<T> withFilter(CsvToBeanFilter filter) { this.filter = filter; return this; }
Params:
  • throwExceptions – Please see the "See Also" section
See Also:
  • setThrowExceptions.setThrowExceptions(boolean)
Returns:this
/** * @see CsvToBean#setThrowExceptions(boolean) * @param throwExceptions Please see the "See Also" section * @return {@code this} */
public CsvToBeanBuilder<T> withThrowExceptions(boolean throwExceptions) { this.throwExceptions = throwExceptions; return this; }
Params:
  • indicator – Which field content will be returned as null: EMPTY_SEPARATORS, EMPTY_QUOTES, BOTH, NEITHER (default)
Returns:this
/** * @param indicator Which field content will be returned as null: EMPTY_SEPARATORS, EMPTY_QUOTES, * BOTH, NEITHER (default) * @return {@code this} */
public CsvToBeanBuilder<T> withFieldAsNull(CSVReaderNullFieldIndicator indicator) { this.nullFieldIndicator = indicator; return this; }
Params:
  • keepCR – True to keep carriage returns in data read, false otherwise
Returns:this
/** * @param keepCR True to keep carriage returns in data read, false otherwise * @return {@code this} */
public CsvToBeanBuilder<T> withKeepCarriageReturn(boolean keepCR) { this.keepCR = keepCR; return this; }
Params:
  • verifyReader – Please see the "See Also" section
See Also:
  • withVerifyReader.withVerifyReader(boolean)
Returns:this
/** * @see CSVReaderBuilder#withVerifyReader(boolean) * @param verifyReader Please see the "See Also" section * @return {@code this} */
public CsvToBeanBuilder<T> withVerifyReader(boolean verifyReader) { this.verifyReader = verifyReader; return this; }
Params:
  • skipLines – Please see the "See Also" section
See Also:
  • withSkipLines.withSkipLines(int)
Returns:this
/** * @see CSVReaderBuilder#withSkipLines(int) * @param skipLines Please see the "See Also" section * @return {@code this} */
public CsvToBeanBuilder<T> withSkipLines( final int skipLines) { this.skipLines = skipLines; return this; }
Params:
  • separator – Please see the "See Also" section
See Also:
  • CSVParser.CSVParser(char, char, char, boolean, boolean, boolean, CSVReaderNullFieldIndicator, Locale)
Returns:this
/** * @see CSVParser#CSVParser(char, char, char, boolean, boolean, boolean, CSVReaderNullFieldIndicator, Locale) * @param separator Please see the "See Also" section * @return {@code this} */
public CsvToBeanBuilder<T> withSeparator(char separator) { this.separator = separator; return this; }
Params:
  • quoteChar – Please see the "See Also" section
See Also:
  • CSVParser.CSVParser(char, char, char, boolean, boolean, boolean, CSVReaderNullFieldIndicator, Locale)
Returns:this
/** * @see CSVParser#CSVParser(char, char, char, boolean, boolean, boolean, CSVReaderNullFieldIndicator, Locale) * @param quoteChar Please see the "See Also" section * @return {@code this} */
public CsvToBeanBuilder<T> withQuoteChar(char quoteChar) { this.quoteChar = quoteChar; return this; }
Params:
  • escapeChar – Please see the "See Also" section
See Also:
  • CSVParser.CSVParser(char, char, char, boolean, boolean, boolean, CSVReaderNullFieldIndicator, Locale)
Returns:this
/** * @see CSVParser#CSVParser(char, char, char, boolean, boolean, boolean, CSVReaderNullFieldIndicator, Locale) * @param escapeChar Please see the "See Also" section * @return {@code this} */
public CsvToBeanBuilder<T> withEscapeChar(char escapeChar) { this.escapeChar = escapeChar; return this; }
Params:
  • strictQuotes – Please see the "See Also" section
See Also:
  • CSVParser.CSVParser(char, char, char, boolean, boolean, boolean, CSVReaderNullFieldIndicator, Locale)
Returns:this
/** * @see CSVParser#CSVParser(char, char, char, boolean, boolean, boolean, CSVReaderNullFieldIndicator, Locale) * @param strictQuotes Please see the "See Also" section * @return {@code this} */
public CsvToBeanBuilder<T> withStrictQuotes(boolean strictQuotes) { this.strictQuotes = strictQuotes; return this; }
Params:
  • ignoreLeadingWhiteSpace – Please see the "See Also" section
See Also:
  • CSVParser.CSVParser(char, char, char, boolean, boolean, boolean, CSVReaderNullFieldIndicator, Locale)
Returns:this
/** * @see CSVParser#CSVParser(char, char, char, boolean, boolean, boolean, CSVReaderNullFieldIndicator, Locale) * @param ignoreLeadingWhiteSpace Please see the "See Also" section * @return {@code this} */
public CsvToBeanBuilder<T> withIgnoreLeadingWhiteSpace(boolean ignoreLeadingWhiteSpace) { this.ignoreLeadingWhiteSpace = ignoreLeadingWhiteSpace; return this; }
Params:
  • ignoreQuotations – Please see the "See Also" section
See Also:
  • CSVParser.CSVParser(char, char, char, boolean, boolean, boolean, CSVReaderNullFieldIndicator, Locale)
Returns:this
/** * @see CSVParser#CSVParser(char, char, char, boolean, boolean, boolean, CSVReaderNullFieldIndicator, Locale) * @param ignoreQuotations Please see the "See Also" section * @return {@code this} */
public CsvToBeanBuilder<T> withIgnoreQuotations(boolean ignoreQuotations) { this.ignoreQuotations = ignoreQuotations; return this; }
Sets the type of the bean to be populated. Ignored if withMappingStrategy(MappingStrategy) is called.
Params:
  • type – Class of the destination bean
See Also:
Returns:this
/** * Sets the type of the bean to be populated. * Ignored if {@link #withMappingStrategy(com.opencsv.bean.MappingStrategy)} * is called. * @param type Class of the destination bean * @return {@code this} * @see HeaderColumnNameMappingStrategy#setType(java.lang.Class) * @see ColumnPositionMappingStrategy#setType(java.lang.Class) */
public CsvToBeanBuilder<T> withType(Class<? extends T> type) { this.type = type; return this; }
Sets the maximum number of lines allowed in a multiline record. More than this number in one record results in an IOException.
Params:
Returns:this
/** * Sets the maximum number of lines allowed in a multiline record. * More than this number in one record results in an IOException. * * @param multilineLimit No more than this number of lines is allowed in a * single input record. The default is {@link CSVReader#DEFAULT_MULTILINE_LIMIT}. * @return {@code this} */
public CsvToBeanBuilder<T> withMultilineLimit(int multilineLimit) { this.multilineLimit = multilineLimit; return this; }
Sets whether the resulting beans must be ordered as in the input.
Params:
  • orderedResults – Whether to order the results or not
See Also:
Returns:this
Since:4.0
/** * Sets whether the resulting beans must be ordered as in the input. * * @param orderedResults Whether to order the results or not * @return {@code this} * @see CsvToBean#setOrderedResults(boolean) * @since 4.0 */
public CsvToBeanBuilder<T> withOrderedResults(boolean orderedResults) { this.orderedResults = orderedResults; return this; }
Sets the locale for all error messages.
Params:
  • errorLocale – Locale for error messages
See Also:
Returns:this
Since:4.0
/** * Sets the locale for all error messages. * * @param errorLocale Locale for error messages * @return {@code this} * @see CsvToBean#setErrorLocale(java.util.Locale) * @since 4.0 */
public CsvToBeanBuilder<T> withErrorLocale(Locale errorLocale) { this.errorLocale = ObjectUtils.defaultIfNull(errorLocale, Locale.getDefault()); return this; }
Adds a BeanVerifier to the list of verifiers to run on all beans created. This method may be called as many times as desired. All added verifiers will be run on every bean. No guarantee is made as to the order in which the verifiers are run.
Params:
  • verifier – A new verifier that is to process all beans after creation. null is permissible but has no effect.
Returns:this
Since:4.4
/** * Adds a {@link BeanVerifier} to the list of verifiers to run on all * beans created. * This method may be called as many times as desired. All added verifiers * will be run on every bean. No guarantee is made as to the order in which * the verifiers are run. * * @param verifier A new verifier that is to process all beans after * creation. {@code null} is permissible but has no effect. * @return {@code this} * @since 4.4 */
public CsvToBeanBuilder<T> withVerifier(BeanVerifier<T> verifier) { if(verifier != null) { verifiers.add(verifier); } return this; }
Adds a Field to the list of fields opencsv should ignore completely.

May be called as many times as necessary.

Params:
  • type – The class opencsv will encounter the field in during processing. In the case of inheritance, this may not be the declaring class.
  • field – The field opencsv is to ignore
Throws:
See Also:
Returns:this
Since:5.0
/** * Adds a {@link Field} to the list of fields opencsv should ignore * completely. * <p>May be called as many times as necessary.</p> * @param type The class opencsv will encounter the field in during * processing. In the case of inheritance, this may not be the * declaring class. * @param field The field opencsv is to ignore * @return {@code this} * @throws IllegalArgumentException If one of the parameters is * {@code null} or {@code field} cannot be found in {@code type}. * @since 5.0 * @see MappingStrategy#ignoreFields(MultiValuedMap) */
public CsvToBeanBuilder<T> withIgnoreField(Class<?> type, Field field) throws IllegalArgumentException { if (type != null && field != null && field.getDeclaringClass().isAssignableFrom(type)) { ignoredFields.put(type, field); } else { throw new IllegalArgumentException(ResourceBundle.getBundle( ICSVParser.DEFAULT_BUNDLE_NAME, errorLocale) .getString("ignore.field.inconsistent")); } return this; }
Params:
  • ignore – Please see the "See Also" section
See Also:
  • CsvToBean.ignoreEmptyLines
Returns:this
/** * @param ignore Please see the "See Also" section * @return {@code this} * @see CsvToBean#ignoreEmptyLines */
public CsvToBeanBuilder<T> withIgnoreEmptyLine(boolean ignore) { this.ignoreEmptyLines = ignore; return this; } }