Skip to content

Instantly share code, notes, and snippets.

@NF1198
Last active March 18, 2018 04:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NF1198/a52962c15b29801ba59fc6759da4602a to your computer and use it in GitHub Desktop.
Save NF1198/a52962c15b29801ba59fc6759da4602a to your computer and use it in GitHub Desktop.
A utility class that makes it easy to build objects from rows in a CSV file
/*
* Copyright 2017 tauTerra, LLC.
*
* 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.tauterra.utility;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.BiConsumer;
import java.util.function.Supplier;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVRecord;
/**
* A utility class that makes it easy to build objects from rows in a CSV file.
* <p>Depends: 'org.apache.commons', name: 'commons-csv', version: '1.5'</p>
* <p>Usage:</p>
* <pre>
* CSVObjectReader&lt;MyObject&gt; myReader = new CSVObjectReader&lt;&gt;(() -> new MyObject());
* myReader.addHandler("colNameA", (MyObject myObj, String value) -> myObj.setFoo(value));
* myReader.addHandler("colNameB", (MyObject myObj, String value) -> myObj.setBar(value));
* List&lt;MyObject&gt; rowsAsObjects = myReader.read(<em>csvInputStream</em>);
* </pre>
*
* @author Nicholas Folse
*/
public class CSVObjectReader<U> {
final Supplier<U> objSupplier;
final Map<String, BiConsumer<U, String>> colByNameHandlers = new HashMap<>();
final List<BiConsumer<U, String>> colByIndexHandlers = new ArrayList<>();
public CSVObjectReader(Supplier<U> objSupplier) {
this.objSupplier = objSupplier;
}
public void addHandler(String columnName, BiConsumer<U, String> handler) {
colByNameHandlers.put(columnName, handler);
}
public void addHandler(int columnIndex, BiConsumer<U, String> handler) {
if (columnIndex > 32000) {
return;
}
while (colByIndexHandlers.size() <= columnIndex) {
colByIndexHandlers.add(null);
}
colByIndexHandlers.set(columnIndex, handler);
}
List<U> read(InputStream is) throws IOException {
List<U> recordList = new ArrayList<>();
try (InputStreamReader reader = new InputStreamReader(is)) {
Iterable<CSVRecord> records = CSVFormat.RFC4180.withFirstRecordAsHeader().parse(reader);
for (CSVRecord record : records) {
U result = objSupplier.get();
for (Entry<String, BiConsumer<U, String>> kv : colByNameHandlers.entrySet()) {
if (record.isMapped(kv.getKey()) && kv.getValue() != null) {
try {
kv.getValue().accept(result, record.get(kv.getKey()));
} catch (IllegalArgumentException e) {
}
}
}
int idx = 0;
for (BiConsumer<U, String> setter : colByIndexHandlers) {
if (setter != null) {
String colValue = record.get(idx++);
if (colValue != null) {
setter.accept(result, colValue);
}
}
}
recordList.add(result);
}
}
return recordList;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment