HeaderIndex.java
- /*
- * 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 {@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. */
- private String[] positionToHeader = ArrayUtils.EMPTY_STRING_ARRAY;
-
- /**
- * 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. */
- public HeaderIndex(){}
-
- /**
- * Empties the entire mapping.
- */
- public void clear() {
- positionToHeader = ArrayUtils.EMPTY_STRING_ARRAY;
- headerToPosition.clear();
- }
-
- /**
- * 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 {@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++;
- }
- }
-
- /** @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.
- *
- * @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.
- *
- * @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;
- }
-
- /**
- * @return The current list of headers mapped by this index in the proper
- * order
- */
- public String[] getHeaderIndex() {
- return ArrayUtils.clone(positionToHeader);
- }
-
- /**
- * @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.
- *
- * @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);
- }
- }