package org.supercsv.util;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.exception.SuperCSVException;
/**
* A utility class for various list/map operations. May be of use to the public as well as to BestCSV
*
* @author Kasper B. Graversen
*/
public abstract class Util {
/**
* Convert a map to a list
*
* @param source
* the map to create a list from
* @param nameMapping
* the keys of the map whose values will constitute the list
* @return a list
*/
public static List<? extends Object> map2List(final Map<String, ? extends Object> source, final String[] nameMapping) {
final List<? super Object> result = new ArrayList<Object>(nameMapping.length);
for( final String element : nameMapping ) {
result.add(source.get(element));
}
return result;
}
/**
* A function to convert a list to a map using a namemapper for defining the keys of the map.
*
* @param destination
* the resulting map instance. The map is cleared before populated
* @param nameMapper
* cannot contain duplicate names
* @param values
* A list of values TODO: see if using an iterator for the values is more efficient
*/
public static <T> void mapStringList(final Map<String, T> destination, final String[] nameMapper, final List<T> values) {
if( nameMapper.length != values.size() ) {
throw new SuperCSVException(
"The namemapper array and the value list must match in size. Number of columns mismatch number of entries for your map.");
}
destination.clear();
// map each element of the array
for( int i = 0; i < nameMapper.length; i++ ) {
final String key = nameMapper[i];
// null's in the name mapping means skip column
if( key == null ) {
continue;
}
// only perform safe inserts
if( destination.containsKey(key) ) {
throw new SuperCSVException("nameMapper array contains duplicate key \"" + key
+ "\" cannot map the list");
}
destination.put(key, values.get(i));
}
}
/**
* A function which given a list of strings, process each cell using its corresponding processor-chain from the
* processor array and return the result as an arary Can be extended so the safety check is cached in case the same two
* arrays are used on several requests
*
* @param destination
* This list is emptied and then populated with the result from reading a line
* @param source
* Is an array of Strings/null's representing the soure elements
* @param processors
* an array of CellProcessors/null's enabling custom processing of each cellvalue specified in the cellValue
* array. The number of non-null entries in the cellValues array must match the number of processors/null
* given.
* @param lineNo
* the line number of the CSV source the processing is taking place on
*/
public static void processStringList(final List<? super Object> destination, final List<? extends Object> source,
final CellProcessor[] processors, final int lineNo) throws SuperCSVException {
final CSVContext context = new CSVContext();
context.lineSource = source;
context.lineNumber = lineNo;
if( source.size() != processors.length ) {
throw new SuperCSVException("The value array (size " + source.size()
+ ") must match the processors array (size " + processors.length + "):"
+ " You are probably reading a CSV line with a different number of columns"
+ " than the number of cellprocessors specified", context);
}
destination.clear();
for( int i = 0; i < source.size(); i++ ) {
// if no processor, just add the string
if( processors[i] == null ) {
destination.add(source.get(i));
}
else {
context.columnNumber = i;
destination.add(processors[i].execute(source.get(i), context)); // add
}
}
}
/**
* Convert a map to an array of objects
*
* @param values
* the values
* @param nameMapping
* the mapping defining the order of the value extract of the map
* @return the map unfolded as an array based on the nameMapping
*/
public static Object[] stringMap(final Map<String, ? extends Object> values, final String[] nameMapping) {
final Object[] res = new Object[nameMapping.length];
int i = 0;
for( final String name : nameMapping ) {
res[i++] = values.get(name);
}
return res;
}
}
|