/*
* The Kuali Financial System, a comprehensive financial management system for higher education.
*
* Copyright 2005-2014 The Kuali Foundation
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kuali.kfs.sys;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.Date;
import java.sql.Timestamp;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import org.apache.commons.lang.time.DateUtils;
import org.kuali.rice.core.api.util.type.KualiDecimal;
public class CSVDataLoader {
private Map<String, String[]> dataMap = new HashMap<String, String[]>();
private Map<String, Integer> headerMap = new HashMap<String, Integer>();
public boolean getBoolean(int pos, String column) {
String columnData = getColumnData(pos, column);
if (columnData == null || columnData.trim().length() == 0) {
return false;
}
return Boolean.valueOf(columnData);
}
public int getColumnCount() {
return this.headerMap.size();
}
private String getColumnData(int recordPos, String columnName) {
String[] dataCols = dataMap.get(String.valueOf(recordPos));
Integer headerPos = headerMap.get(columnName.trim().toUpperCase());
if (dataCols != null && headerPos != null) {
return dataCols[headerPos];
}
return null;
}
public Set<String> getColumns() {
return this.headerMap.keySet();
}
public Date getDate(int pos, String column) throws ParseException {
String columnData = getColumnData(pos, column);
if (columnData == null || columnData.trim().length() == 0) {
return null;
}
return new Date(DateUtils.parseDate(columnData, new String[] { "MM/dd/yyyy hh:mm:ss a", "MM/dd/yyyy" }).getTime());
}
public Integer getInteger(int pos, String column) {
String columnData = getColumnData(pos, column);
if (columnData == null || columnData.trim().length() == 0) {
return null;
}
return Integer.valueOf(columnData);
}
public KualiDecimal getKualiDecimal(int pos, String column) {
String columnData = getColumnData(pos, column);
if (columnData == null || columnData.trim().length() == 0) {
columnData = "0";
}
return new KualiDecimal(columnData);
}
public Long getLong(int pos, String column) {
String columnData = getColumnData(pos, column);
if (columnData == null || columnData.trim().length() == 0) {
return null;
}
return Long.valueOf(columnData);
}
public int getRowCount() {
return this.dataMap.size();
}
public String getString(int recordPos, String columnName) {
return getColumnData(recordPos, columnName);
}
public Timestamp getTimestamp(int pos, String column) throws ParseException {
String columnData = getColumnData(pos, column);
if (columnData == null || columnData.trim().length() == 0) {
return null;
}
return new Timestamp(DateUtils.parseDate(columnData, new String[] { "MM/dd/yyyy hh:mm:ss a", "MM/dd/yyyy" }).getTime());
}
public void loadData(String resourceName, boolean quoted) {
BufferedReader reader = null;
try {
InputStream systemResourceAsStream = ClassLoader.getSystemResourceAsStream(resourceName);
reader = new BufferedReader(new InputStreamReader(systemResourceAsStream));
String line = null;
String[] dataCols = null;
int headerPos = 0;
int pos = -1;
while ((line = reader.readLine()) != null) {
if (quoted) {
dataCols = parseQuoted(line, ",");
}
else {
dataCols = line.split(",", -1);
}
if (pos == -1) {
for (String hdr : dataCols) {
headerMap.put(hdr.trim().toUpperCase(), headerPos++);
}
}
else {
dataMap.put(String.valueOf(pos), dataCols);
}
pos++;
}
}
catch (Exception e) {
throw new RuntimeException(e);
}
finally {
if (reader != null) {
try {
reader.close();
reader = null;
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
private String[] parseQuoted(String record, String delimiter) {
if (record == null) {
return null;
}
String value = record.trim();
// adjust first quote
value = value.replaceAll("^\"", "");
// adjust first delimiter
value = value.replaceAll("^" + delimiter, " \"" + delimiter);
// adjust last quote
value = value.replaceAll("\"$", "");
// adjust last delimiter
value = value.replaceAll(delimiter + "$", delimiter + "\"");
// adjust adjacent empty delimiters
String regEx = "(.*)\"( *)" + delimiter + "( *)" + delimiter + "(.*)";
while (Pattern.matches(regEx, value)) {
value = value.replaceAll("\" *" + delimiter + " *" + delimiter, "\"" + delimiter + "\"\"" + delimiter);
}
return value.split("\" *" + delimiter + " *\"", -1);
}
public void reset() {
this.dataMap.clear();
this.dataMap = new HashMap<String, String[]>();
this.headerMap.clear();
this.headerMap = new HashMap<String, Integer>();
}
}