/**
* This file is licensed under the University of Illinois/NCSA Open Source License. See LICENSE.TXT for details.
*/
package edu.illinois.codingspectator.csvtotransactions;
import java.io.IOException;
import java.io.Reader;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.supercsv.io.CsvMapReader;
import org.supercsv.prefs.CsvPreference;
/**
*
* @author Mohsen Vakilian
*
*/
public class CSVReader implements Iterable<Map<String, String>> {
private CsvMapReader csvMapReader;
private String[] csvHeader;
private String[] requiredCSVColumns;
public CSVReader(Reader reader) {
csvMapReader= new CsvMapReader(reader, CsvPreference.EXCEL_PREFERENCE);
}
public CSVReader(Reader reader, String[] requiredCSVHeader) {
this(reader);
this.requiredCSVColumns= requiredCSVHeader;
}
private void readHeader() throws IOException {
if (csvHeader != null) {
return;
}
csvHeader= csvMapReader.getCSVHeader(true);
if (requiredCSVColumns != null) {
if (!isCSVHeaderValid()) {
throw new RuntimeException("Expected CSV header:\n" + Arrays.toString(requiredCSVColumns) + "got:\n" + Arrays.toString(csvHeader));
}
}
}
public List<String> getHeader() throws IOException {
readHeader();
return Arrays.asList(csvHeader);
}
private boolean isCSVHeaderValid() {
List<String> csvHeaderList= Arrays.asList(csvHeader);
List<String> requiredCSVHeaderList= Arrays.asList(requiredCSVColumns);
return csvHeaderList.containsAll(requiredCSVHeaderList);
}
private Map<String, String> getNextRow() throws IOException {
return csvMapReader.read(csvHeader);
}
@Override
public Iterator<Map<String, String>> iterator() {
return new CSVRowIterator();
}
public class CSVRowIterator implements Iterator<Map<String, String>> {
boolean hasReadHeader= false;
boolean hasComputedNext= false;
Map<String, String> prospectiveNext= null;
private void computeNext() {
try {
if (!hasReadHeader) {
readHeader();
hasReadHeader= true;
}
prospectiveNext= getNextRow();
hasComputedNext= true;
} catch (IOException e) {
throw new RuntimeException("Failed to retrieve the next row.");
}
}
@Override
public boolean hasNext() {
if (!hasComputedNext) {
computeNext();
}
return prospectiveNext != null;
}
@Override
public Map<String, String> next() {
if (!hasComputedNext) {
computeNext();
}
hasComputedNext= false;
return prospectiveNext;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
}