/*
Open Data Service
Copyright (C) 2013 Tsysin Konstantin, Reischl Patrick
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.jvalue.ods.processor.adapter;
import com.codahale.metrics.MetricRegistry;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.jvalue.ods.api.sources.DataSource;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Iterator;
final class CsvSourceAdapter extends AbstractSourceAdapter {
private final CSVFormat csvFormat;
@Inject
CsvSourceAdapter(
@Assisted DataSource source,
@Assisted(SourceAdapterFactory.ARGUMENT_SOURCE_URL) String sourceUrl,
@Assisted(SourceAdapterFactory.ARGUMENT_CSV_FORMAT) String csvFormatString,
MetricRegistry registry) {
super(source, sourceUrl, registry);
switch (csvFormatString) {
case "DEFAULT":
csvFormat = CSVFormat.DEFAULT;
break;
case "EXCEL":
csvFormat = CSVFormat.EXCEL;
break;
case "MYSQL":
csvFormat = CSVFormat.MYSQL;
break;
case "RFC4180":
csvFormat = CSVFormat.RFC4180;
break;
case "TDF":
csvFormat = CSVFormat.TDF;
break;
default:
throw new IllegalArgumentException("unknown csv format \"" + csvFormatString + "\"");
}
}
@Override
protected SourceIterator doCreateIterator(DataSource source, URL sourceUrl, MetricRegistry registry) {
return new CsvSourceIterator(source, sourceUrl, csvFormat, registry);
}
private static final class CsvSourceIterator extends SourceIterator {
private Iterator<CSVRecord> csvIterator;
private CSVRecord firstRecord;
public CsvSourceIterator(DataSource source, URL sourceUrl, CSVFormat csvFormat, MetricRegistry registry) throws SourceAdapterException {
super(source, sourceUrl, registry);
try {
CSVParser parser = CSVParser.parse(sourceUrl, Charset.forName("UTF-8"), csvFormat);
csvIterator = parser.iterator();
firstRecord = csvIterator.next();
} catch (IOException ioe) {
throw new SourceAdapterException(ioe);
}
}
@Override
protected boolean doHasNext() {
return csvIterator.hasNext();
}
@Override
protected ObjectNode doNext() {
return createObject(firstRecord, csvIterator.next());
}
private ObjectNode createObject(CSVRecord keys, CSVRecord values) {
ObjectNode node = new ObjectNode(JsonNodeFactory.instance);
for (int i = 0; i < keys.size(); ++i) {
node.put(keys.get(i), values.get(i));
}
return node;
}
}
}