
net.sf.jtables.io.reader.ReaderTableAbstract Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jtables Show documentation
Show all versions of jtables Show documentation
Simple and lightweight framework to work with tables and table based files such as CSV and other (tab)-delimited files.
/**********************************************************************
Copyright (c) 2009-2012 Alexander Kerner. All rights reserved.
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 net.sf.jtables.io.reader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Scanner;
import net.sf.jtables.table.Row;
import net.sf.jtables.table.TableAnnotated;
import net.sf.jtables.table.TableMutableAnnotated;
import net.sf.jtables.table.impl.RowImpl;
import net.sf.kerner.utils.ObjectPair;
import net.sf.kerner.utils.io.buffered.AbstractIOIterator;
import net.sf.kerner.utils.io.buffered.IOIterator;
/**
* Prototype implementation for {@link ReaderTable}.
*
* Example:
*
*
*
*
* TODO example
*
*
*
*
* @author Alexander Kerner
* @version 2013-01-24
* @param
* type of elements in {@code Table}
*/
public abstract class ReaderTableAbstract extends AbstractIOIterator> implements ReaderTable {
/**
* Default column delimiter (tab).
*/
public final static String DEFAULT_DELIM = "\t";
/**
* Does the table have column headers?
*/
protected final boolean colsB;
/**
* column headers.
*/
protected final List columnHeaders = new ArrayList();
/**
* column delimiter.
*/
protected final String delim;
/**
* currently reading first line?
*/
private volatile boolean firstLine = true;
/**
* row headers.
*/
protected final List rowHeaders = new ArrayList();
/**
* Does the table have row headers?
*/
protected final boolean rowsB;
private Collection extends ObjectPair> filterRegex = new ArrayList>();
public ReaderTableAbstract(final File file) throws IOException {
this(file, false, false, null);
}
/**
* Create a new {@code AbstractTableReader}.
*
* @param file
* {@link File} from which table is read
* @param columnIds
* {@code true}, if columns have headers; {@code false} otherwise
* @param rowIds
* {@code true}, if rows have headers; {@code false} otherwise
* @throws IOException
* if anything goes wrong
*/
public ReaderTableAbstract(final File file, final boolean columnIds, final boolean rowIds) throws IOException {
this(file, columnIds, rowIds, null);
}
/**
* Create a new {@code AbstractTableReader}.
*
* @param file
* {@link File} from which table is read
* @param columnIds
* {@code true}, if columns have headers; {@code false} otherwise
* @param rowIds
* {@code true}, if rows have headers; {@code false} otherwise
* @param delim
* column delimiter to use
* @throws IOException
* if anything goes wrong
*/
public ReaderTableAbstract(final File file, final boolean columnIds, final boolean rowIds, final String delim)
throws IOException {
this(new FileInputStream(file), columnIds, rowIds, delim);
}
/**
* Create a new {@code AbstractTableReader}.
*
* @param stream
* {@link InputStream} from which table is read
* @param columnIds
* {@code true}, if columns have headers; {@code false} otherwise
* @param rowIds
* {@code true}, if rows have headers; {@code false} otherwise
* @throws IOException
* if anything goes wrong
*/
public ReaderTableAbstract(final InputStream stream, final boolean columnIds, final boolean rowIds)
throws IOException {
this(stream, columnIds, rowIds, null);
}
/**
* Create a new {@code AbstractTableReader}.
*
* @param stream
* {@link InputStream} from which table is read
* @param columnIds
* {@code true}, if columns have headers; {@code false} otherwise
* @param rowIds
* {@code true}, if rows have headers; {@code false} otherwise
* @param delim
* column delimiter to use
* @throws IOException
* if anything goes wrong
*/
public ReaderTableAbstract(final InputStream stream, final boolean columnIds, final boolean rowIds,
final String delim) throws IOException {
super(stream);
this.colsB = columnIds;
this.rowsB = rowIds;
if (delim == null)
this.delim = DEFAULT_DELIM;
else
this.delim = delim;
}
/**
* Create a new {@code AbstractTableReader}.
*
* @param reader
* {@link Reader} from which table is read
* @param columnIds
* {@code true}, if columns have headers; {@code false} otherwise
* @param rowIds
* {@code true}, if rows have headers; {@code false} otherwise
* @throws IOException
* if anything goes wrong
*/
public ReaderTableAbstract(final Reader reader, final boolean columnIds, final boolean rowIds) throws IOException {
this(reader, columnIds, rowIds, null);
}
/**
* Create a new {@code AbstractTableReader}.
*
* @param reader
* {@link Reader} from which table is read
* @param columnIds
* {@code true}, if columns have headers; {@code false} otherwise
* @param rowIds
* {@code true}, if rows have headers; {@code false} otherwise
* @param delim
* column delimiter to use
* @throws IOException
* if anything goes wrong
*/
public ReaderTableAbstract(final Reader reader, final boolean columnIds, final boolean rowIds, final String delim)
throws IOException {
super(reader);
this.colsB = columnIds;
this.rowsB = rowIds;
if (delim == null)
this.delim = DEFAULT_DELIM;
else
this.delim = delim;
}
/**
* Read the next {@link Row} from input source.
*
* @return next {@link Row} or {@code null} if nothing left to read
*/
@Override
protected Row doRead() throws IOException {
String line = reader.readLine();
if (line == null) {
return null;
}
for (final ObjectPair s : filterRegex) {
line = line.replaceAll(s.getFirst(), s.getSecond());
}
if (colsB && firstLine) {
columnHeaders.addAll(getColHeaders(line));
firstLine = false;
// column headers read, continue to next line
line = reader.readLine();
if (line == null)
return null;
}
Scanner scanner = null;
try {
scanner = new Scanner(line);
scanner.useDelimiter(delim);
final RowImpl result = new RowImpl();
// first column (row headers)?
boolean first = true;
while (scanner.hasNext()) {
final String s = scanner.next();
// if(UtilStrings.emptyString(s)){
// continue;
// }
if (rowsB && first) {
rowHeaders.add(s);
first = false;
} else {
result.add(parse(s));
}
}
if (result.isEmpty())
return null;
result.setIdentifier(columnHeaders);
return result;
} finally {
if (scanner != null) {
scanner.close();
}
}
}
/**
* Extract column headers from first line.
*
* @param line
* {@code String} that contains column headers
* @return {@link List} of column headers
*/
protected List getColHeaders(final String line) {
final Scanner scanner = new Scanner(line);
scanner.useDelimiter(delim);
final List list = new ArrayList();
while (scanner.hasNext()) {
final String s = scanner.next();
list.add(s);
}
scanner.close();
return list;
}
public synchronized List getColumnHeaders() throws IOException {
if (colsB && firstLine) {
columnHeaders.addAll(getColHeaders(reader.readLine()));
firstLine = false;
}
return columnHeaders;
}
public synchronized Collection extends ObjectPair> getFilterRegex() {
return filterRegex;
}
/**
*
*/
protected abstract TableMutableAnnotated getInstance();
/**
*
*/
public IOIterator> getIterator() throws IOException {
return this;
}
public synchronized List getRowHeaders() throws IOException {
return rowHeaders;
}
/**
* Parse an object of type {@code T} from given string.
*
* @param s
* {@link String} to parse from
* @return object of type {@code T} that was parsed
* @throws NumberFormatException
* if parsing fails
*/
protected abstract T parse(String s) throws NumberFormatException;
public synchronized TableAnnotated readTableAtOnce() throws IOException {
final TableMutableAnnotated result = getInstance();
final IOIterator> it = getIterator();
while (it.hasNext()) {
final Row next = it.next();
result.addRow(next);
}
it.close();
result.setRowIdentifier(rowHeaders);
result.setColumnIdentifier(columnHeaders);
return result;
}
public synchronized ReaderTableAbstract setFilterRegex(
final Collection extends ObjectPair> regexFilter) {
this.filterRegex = regexFilter;
return this;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy