/*
 * Copyright 2018 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 java.util.Arrays;
import java.util.Collection;
import org.apache.commons.collections4.MultiValuedMap;
import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
import org.apache.commons.lang3.ArrayUtils;

A bi-directional mapping between column positions and header names. A simple BidiMap will not do the trick, because header names (or null in place of a header name) may appear more than once.
Author:Andrew Rucker Jones
Since:4.2
/** * A bi-directional mapping between column positions and header names. * A simple {@link org.apache.commons.collections4.BidiMap} will not do the * trick, because header names (or null in place of a header name) may appear * more than once. * * @author Andrew Rucker Jones * @since 4.2 */
public class HeaderIndex {
The uni-directional map from column position to header name.
/** The uni-directional map from column position to header name. */
private String[] positionToHeader = ArrayUtils.EMPTY_STRING_ARRAY;
The uni-directional map from header name to (possibly multiple) column positions.
/** * The uni-directional map from header name to (possibly multiple) column * positions. */
private MultiValuedMap<String, Integer> headerToPosition = new ArrayListValuedHashMap<>();
Useless but explicit nullary constructor to make the style checker happy.
/** Useless but explicit nullary constructor to make the style checker happy. */
public HeaderIndex(){}
Empties the entire mapping.
/** * Empties the entire mapping. */
public void clear() { positionToHeader = ArrayUtils.EMPTY_STRING_ARRAY; headerToPosition.clear(); }
Finds and returns the highest index in this mapping.
Returns:The maximum index that is mapped and will return a header name (or null if specifically mapped that way). If there are no columns in the mapping, returns -1.
/** * Finds and returns the highest index in this mapping. * @return The maximum index that is mapped and will return a header name * (or null if specifically mapped that way). If there are no columns in * the mapping, returns -1. */
public int findMaxIndex() { return positionToHeader.length-1; }
Initializes the index with a list of header names in proper encounter order. "Proper encounter order" means the order in which they are expected to be found in the input CSV. Header names may be listed more than once if the destination field is annotated with CsvBindAndJoinByPosition or CsvBindAndJoinByName. Values of null indicate the column from the input should not be mapped to a bean field.
Params:
  • header – A list of header names in the order in which they are expected in the CSV input
/** * Initializes the index with a list of header names in proper encounter * order. * "Proper encounter order" means the order in which they are expected to be * found in the input CSV. Header names may be listed more than once if the * destination field is annotated with {@link CsvBindAndJoinByPosition} or * {@link CsvBindAndJoinByName}. Values of {@code null} indicate the column * from the input should not be mapped to a bean field. * * @param header A list of header names in the order in which they are * expected in the CSV input */
public void initializeHeaderIndex(String[] header) { positionToHeader = header != null ? ArrayUtils.clone(header): ArrayUtils.EMPTY_STRING_ARRAY; headerToPosition.clear(); int i = 0; while(i < positionToHeader.length) { headerToPosition.put(header[i], i); i++; } }
Returns:Whether or not the mapping is empty
/** @return Whether or not the mapping is empty */
public boolean isEmpty() { return positionToHeader.length == 0; }
Retrieves the column position(s) associated with the given header name.
Params:
  • headerName – The header name for which the associated column positions should be returned
Returns:The column positions associated with headerName
/** * Retrieves the column position(s) associated with the given header name. * * @param headerName The header name for which the associated column * positions should be returned * @return The column positions associated with {@code headerName} */
public int[] getByName(String headerName) { Collection<Integer> positions = headerToPosition.get(headerName); if(positions != null) { return ArrayUtils.toPrimitive(positions.toArray(ArrayUtils.EMPTY_INTEGER_OBJECT_ARRAY)); } return ArrayUtils.EMPTY_INT_ARRAY; }
Retrieves the header associated with the given column position.
Params:
  • i – The column position for which the header name is to be retrieved
Returns:The header name mapped by position i
/** * Retrieves the header associated with the given column position. * * @param i The column position for which the header name is to be retrieved * @return The header name mapped by position {@code i} */
public String getByPosition(int i) { if(i < positionToHeader.length) { return positionToHeader[i]; } return null; }
Returns:The current list of headers mapped by this index in the proper order
/** * @return The current list of headers mapped by this index in the proper * order */
public String[] getHeaderIndex() { return ArrayUtils.clone(positionToHeader); }
Returns:The length of the current mapping, including all fields unmapped
/** * @return The length of the current mapping, including all fields unmapped */
public int getHeaderIndexLength() {return positionToHeader.length;}
Adds a new mapping between a column position and a header. The header may already be present, in which case the column position is added to the list of column positions mapped to the header.
Params:
  • k – The column position for the mapping
  • v – The header to be associated with the column position
/** * Adds a new mapping between a column position and a header. * The header may already be present, in which case the column position is * added to the list of column positions mapped to the header. * * @param k The column position for the mapping * @param v The header to be associated with the column position */
public void put(int k, String v) { if(k >= positionToHeader.length) { positionToHeader = Arrays.copyOf(positionToHeader, k+1); positionToHeader[k] = v; } headerToPosition.put(v, k); } }