/*
* Copyright (C) 2010 Brockmann Consult GmbH (info@brockmann-consult.de)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU 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 General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, see http://www.gnu.org/licenses/
*/
package com.bc.ceres.site.util;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.Reader;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.List;
import java.util.ArrayList;
// copied from package org.esa.beam.util.io in module beam-core
/**
* A <code>CsvReader</code> instance is used read text files with CSV (comma separated values) format.
* <p/>
* <_p> This reader interpretes each line of a text file as record (also empty lines). The fields of the record are
* delimited by a single separator character which must not necessarily be a comma.
*
* @author Norman Fomferra
* @version 1.0
*/
public class CsvReader extends LineNumberReader {
/**
* The column separator characters.
*/
private final char[] _separators;
/**
* Empty lines ignored?
*/
private final boolean _ignoreEmptyLines;
/**
* The comment prefix string (if any)
*/
private final String _commentPrefix;
/**
* Constructs a CSV reader using the given column separator characters. The new reader will not ignore empty lines
* and does not recognize comment lines.
*
* @param reader the underlying reader to be wrapped
* @param separators the column separator characters
*/
public CsvReader(Reader reader, char[] separators) {
this(reader, separators, false, null);
}
/**
* Constructs a CSV reader using the given column separator characters and the format properties.
*
* @param reader the underlying reader to be wrapped
* @param separators the column separator characters
* @param ignoreEmptyLines if <code>true</code>, empty lines are ignored
* @param commentPrefix if not <code>null</code>, the prefix string for commment lines
*/
public CsvReader(Reader reader, char[] separators, boolean ignoreEmptyLines, String commentPrefix) {
super(reader);
_separators = separators;
_ignoreEmptyLines = ignoreEmptyLines;
_commentPrefix = commentPrefix;
}
/**
* Gets the column separator characters.
*/
public final char[] getSeparators() {
return _separators;
}
/**
* Are empty lines ignored?
*/
public final boolean ignoresEmptyLines() {
return _ignoreEmptyLines;
}
/**
* Gets the comment prefix string (if any).
*/
public final String getCommentPrefix() {
return _commentPrefix;
}
/**
* Reads a record info from the database. A record is represented by a complete line in the CSV formatted text
* file.
* <p/>
* <_p> Leading and trailing whitespaces removed from each column value. For empty lines, the method returns an
* array of the length zero. The method returns <code>null</code> if the end of file has been reached.
*
* @return a record containing the tokens delimitted by the separator character passed to the constructor
*
* @throws IOException if an I/O error occurs
*/
public String[] readRecord() throws IOException {
String line;
while (true) {
line = readLine();
if (line == null) {
return null;
}
line = line.trim();
if (ignoresEmptyLines() && line.length() == 0) {
// Ok, next line
} else if (getCommentPrefix() != null && line.startsWith(getCommentPrefix())) {
// Ok, next line
} else {
break;
}
}
StringTokenizer st = new StringTokenizer(line, new String(getSeparators()));
String[] tokens = new String[st.countTokens()];
for (int i = 0; i < tokens.length; i++) {
tokens[i] = st.nextToken().trim();
}
return tokens;
}
public double[] readDoubleRecord() throws IOException {
String[] stringRecord = readRecord();
if (stringRecord == null) {
return null;
}
double[] doubleRecord = new double[stringRecord.length];
for (int i = 0; i < doubleRecord.length; i++) {
try {
doubleRecord[i] = Double.parseDouble(stringRecord[i]);
} catch (NumberFormatException e) {
throw new IOException(e);
}
}
return doubleRecord;
}
/**
* Reads the complete file from the current position on. If the <code>readLineRecord</code> has not previously been
* called the method reads all records from the beginning of the file. For empty files, the method returns an vector
* having a zero size.
*
* @return an vector of <code>String[]</code> records containing the tokens delimitted by the separator character
* passed to the constructor
*
* @throws IOException if an I/O error occurs
* @deprecated in 4.0, use #readStringRecords
*/
public Vector<String[]> readAllRecords() throws IOException {
Vector<String[]> vector = new Vector<String[]>(256);
String[] record;
while ((record = readRecord()) != null) {
vector.add(record);
}
vector.trimToSize();
return vector;
}
public List<String[]> readStringRecords() throws IOException {
return readAllRecords();
}
public List<double[]> readDoubleRecords() throws IOException {
ArrayList<double[]> vector = new ArrayList<double[]>(256);
double[] record;
while ((record = readDoubleRecord()) != null) {
vector.add(record);
}
vector.trimToSize();
return vector;
}
}