package com.opencsv.bean;

import org.apache.commons.collections4.ListValuedMap;
import org.apache.commons.collections4.MultiValuedMap;
import org.apache.commons.lang3.StringUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.*;

/*
 * Copyright 2007 Kyle Miller.
 *
 * 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.
 */

Maps data to objects using the column names in the first row of the CSV file as reference. This way the column order does not matter.
Type parameters:
  • <T> – Type of the bean to be returned
/** * Maps data to objects using the column names in the first row of the CSV file * as reference. This way the column order does not matter. * * @param <T> Type of the bean to be returned */
public class HeaderColumnNameMappingStrategy<T> extends HeaderNameBaseMappingStrategy<T> {
Default constructor.
/** * Default constructor. */
public HeaderColumnNameMappingStrategy() { }
Creates a map of annotated fields in the bean to be processed.

This method is called by AbstractMappingStrategy.loadFieldMap() when at least one relevant annotation is found on a member variable.

/** * Creates a map of annotated fields in the bean to be processed. * <p>This method is called by {@link #loadFieldMap()} when at least one * relevant annotation is found on a member variable.</p> */
@Override protected void loadAnnotatedFieldMap(ListValuedMap<Class<?>, Field> fields) { boolean required; for (Map.Entry<Class<?>, Field> classField : fields.entries()) { Class<?> localType = classField.getKey(); Field localField = classField.getValue(); String columnName, locale, writeLocale, capture, format; // Always check for a custom converter first. if (localField.isAnnotationPresent(CsvCustomBindByName.class)) { CsvCustomBindByName annotation = localField .getAnnotation(CsvCustomBindByName.class); columnName = annotation.column().toUpperCase().trim(); if(StringUtils.isEmpty(columnName)) { columnName = localField.getName().toUpperCase(); } @SuppressWarnings("unchecked") Class<? extends AbstractBeanField<T, String>> converter = (Class<? extends AbstractBeanField<T, String>>)localField .getAnnotation(CsvCustomBindByName.class) .converter(); BeanField<T, String> bean = instantiateCustomConverter(converter); bean.setType(localType); bean.setField(localField); required = annotation.required(); bean.setRequired(required); fieldMap.put(columnName, bean); } // Then check for a collection else if(localField.isAnnotationPresent(CsvBindAndSplitByName.class)) { CsvBindAndSplitByName annotation = localField .getAnnotation(CsvBindAndSplitByName.class); required = annotation.required(); columnName = annotation.column().toUpperCase().trim(); locale = annotation.locale(); writeLocale = annotation.writeLocaleEqualsReadLocale() ? locale : annotation.writeLocale(); String splitOn = annotation.splitOn(); String writeDelimiter = annotation.writeDelimiter(); Class<? extends Collection> collectionType = annotation.collectionType(); Class<?> elementType = annotation.elementType(); Class<? extends AbstractCsvConverter> splitConverter = annotation.converter(); capture = annotation.capture(); format = annotation.format(); CsvConverter converter = determineConverter( localField, elementType, locale, writeLocale, splitConverter); if (StringUtils.isEmpty(columnName)) { fieldMap.put(localField.getName().toUpperCase(), new BeanFieldSplit<>( localType, localField, required, errorLocale, converter, splitOn, writeDelimiter, collectionType, capture, format)); } else { fieldMap.put(columnName, new BeanFieldSplit<>( localType, localField, required, errorLocale, converter, splitOn, writeDelimiter, collectionType, capture, format)); } } // Then for a multi-column annotation else if(localField.isAnnotationPresent(CsvBindAndJoinByName.class)) { CsvBindAndJoinByName annotation = localField .getAnnotation(CsvBindAndJoinByName.class); required = annotation.required(); String columnRegex = annotation.column(); locale = annotation.locale(); writeLocale = annotation.writeLocaleEqualsReadLocale() ? locale : annotation.writeLocale(); Class<?> elementType = annotation.elementType(); Class<? extends MultiValuedMap> mapType = annotation.mapType(); Class<? extends AbstractCsvConverter> joinConverter = annotation.converter(); capture = annotation.capture(); format = annotation.format(); CsvConverter converter = determineConverter( localField, elementType, locale, writeLocale, joinConverter); if (StringUtils.isEmpty(columnRegex)) { fieldMap.putComplex(localField.getName(), new BeanFieldJoinStringIndex<>( localType, localField, required, errorLocale, converter, mapType, capture, format)); } else { fieldMap.putComplex(columnRegex, new BeanFieldJoinStringIndex<>( localType, localField, required, errorLocale, converter, mapType, capture, format)); } } // Otherwise it must be CsvBindByName. else { CsvBindByName annotation = localField.getAnnotation(CsvBindByName.class); required = annotation.required(); columnName = annotation.column().toUpperCase().trim(); locale = annotation.locale(); writeLocale = annotation.writeLocaleEqualsReadLocale() ? locale : annotation.writeLocale(); capture = annotation.capture(); format = annotation.format(); CsvConverter converter = determineConverter( localField, localField.getType(), locale, writeLocale, null); if (StringUtils.isEmpty(columnName)) { fieldMap.put(localField.getName().toUpperCase(), new BeanFieldSingleValue<>( localType, localField, required, errorLocale, converter, capture, format)); } else { fieldMap.put(columnName, new BeanFieldSingleValue<>( localType, localField, required, errorLocale, converter, capture, format)); } } } }
Returns a set of the annotations that are used for binding in this mapping strategy.

In this mapping strategy, those are currently:

/** * Returns a set of the annotations that are used for binding in this * mapping strategy. * <p>In this mapping strategy, those are currently:<ul> * <li>{@link CsvBindByName}</li> * <li>{@link CsvCustomBindByName}</li> * <li>{@link CsvBindAndJoinByName}</li> * <li>{@link CsvBindAndSplitByName}</li> * </ul></p> */
@Override protected Set<Class<? extends Annotation>> getBindingAnnotations() { // With Java 9 this can be done more easily with Set.of() return new HashSet<>(Arrays.asList( CsvBindByName.class, CsvCustomBindByName.class, CsvBindAndSplitByName.class, CsvBindAndJoinByName.class)); } }