package fr.openwide.core.imports.table.opencsv.scanner;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import org.apache.commons.io.filefilter.FileFilterUtils;
import org.apache.commons.lang3.Validate;
import com.opencsv.CSVReader;
import de.schlichtherle.truezip.file.TFileInputStream;
import fr.openwide.core.imports.table.common.csv.scanner.ICsvImportFileScanner;
import fr.openwide.core.imports.table.common.event.exception.TableImportException;
import fr.openwide.core.imports.table.common.event.exception.TableImportFileException;
import fr.openwide.core.imports.table.opencsv.location.OpenCsvImportNavigator;
import fr.openwide.core.imports.table.opencsv.model.CsvCell;
import fr.openwide.core.imports.table.opencsv.model.CsvCellReference;
import fr.openwide.core.imports.table.opencsv.model.CsvRow;
import fr.openwide.core.imports.table.opencsv.model.CsvTable;
public class OpenCsvImportFileScanner implements ICsvImportFileScanner<CsvTable, CsvRow, CsvCell, CsvCellReference> {
private static final String HIDDEN_FILE_PREFIX = ".";
// Default is to scan all files except hidden files and files in hidden directories.
public static final FileFilter DEFAULT_DIRECTORY_CHILD_FILTER = FileFilterUtils.notFileFilter(FileFilterUtils.prefixFileFilter(HIDDEN_FILE_PREFIX));
/**
* A shorthand for implementing {@code ICsvImportFileVisitor<CsvSheet, CsvRow, CsvCell, CsvCellReference>} without writing
* down the generics (which is painful).
*/
public interface IOpenCsvImportFileVisitor extends ICsvImportFileVisitor<CsvTable, CsvRow, CsvCell, CsvCellReference>{
}
protected FileFilter getDirectoryChildFilter() {
return DEFAULT_DIRECTORY_CHILD_FILTER;
}
@Override
public void scanRecursively(File file, String filename, ICsvImportFileVisitor<CsvTable, CsvRow, CsvCell, CsvCellReference> visitor) throws TableImportException {
Validate.notNull(file, "file must not be null");
Validate.notNull(visitor, "visitor must not be null");
if (file.isDirectory()) {
// Recurse
FileFilter filter = getDirectoryChildFilter();
for (File child : file.listFiles(filter)) {
scanRecursively(child, child.getName(), visitor);
}
} else {
scan(file, filename, visitor);
}
}
protected Reader createReader(InputStream inputStream, String filename) throws IOException {
return new InputStreamReader(inputStream);
}
protected CSVReader createCsvReader(Reader reader, String filename) {
return new CSVReader(reader);
}
@Override
public void scan(File file, String filename, ICsvImportFileVisitor<CsvTable, CsvRow, CsvCell, CsvCellReference> visitor) throws TableImportException {
Validate.notNull(file, "file must not be null");
Validate.notNull(visitor, "visitor must not be null");
OpenCsvImportNavigator navigator = new OpenCsvImportNavigator(filename);
try (
InputStream stream = new TFileInputStream(file);
Reader reader = createReader(stream, filename);
CSVReader csvReader = createCsvReader(reader, filename)
) {
CsvTable sheet = new CsvTable(csvReader.readAll());
visitor.visitTable(navigator, sheet);
} catch (IOException e) {
throw new TableImportFileException(e, navigator.getLocation(null, null, null));
}
}
@Override
public void scan(InputStream stream, String filename, ICsvImportFileVisitor<CsvTable, CsvRow, CsvCell, CsvCellReference> visitor) throws TableImportException {
Validate.notNull(stream, "stream must not be null");
Validate.notNull(visitor, "visitor must not be null");
OpenCsvImportNavigator navigator = new OpenCsvImportNavigator(filename);
try (
Reader reader = createReader(stream, filename);
CSVReader csvReader = createCsvReader(reader, filename)
) {
CsvTable sheet = new CsvTable(csvReader.readAll());
visitor.visitTable(navigator, sheet);
} catch (IOException e) {
throw new TableImportFileException(e, navigator.getLocation(null, null, null));
}
}
}