/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2010-2015, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library 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 * Lesser General Public License for more details. */ package org.geotoolkit.data.csv; import com.vividsolutions.jts.io.ParseException; import com.vividsolutions.jts.io.WKTReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Scanner; import java.util.concurrent.locks.ReadWriteLock; import org.apache.sis.storage.DataStoreException; import org.apache.sis.util.ObjectConverters; import org.geotoolkit.data.FeatureReader; import org.geotoolkit.data.FeatureStoreRuntimeException; import org.opengis.feature.AttributeType; import org.opengis.feature.Feature; import org.opengis.feature.FeatureType; import org.opengis.feature.Operation; import org.opengis.feature.PropertyType; import org.apache.sis.internal.feature.AttributeConvention; /** * * @author Johann Sorel (Geomatys) */ class CSVFeatureReader implements FeatureReader { protected final CSVFeatureStore store; protected final ReadWriteLock fileLock; protected final FeatureType featureType; protected final WKTReader reader = new WKTReader(); protected final Scanner scanner; protected final AttributeType[] atts; protected final Feature reuse; protected Feature current = null; protected int inc = 0; CSVFeatureReader(CSVFeatureStore store, final FeatureType featureType, final boolean reuseFeature, final ReadWriteLock fileLock) throws DataStoreException { this.store = store; this.fileLock = fileLock; this.featureType = featureType; this.fileLock.readLock().lock(); if (reuseFeature) { reuse = CSVUtils.defaultFeature(featureType, "0"); } else { reuse = null; } try { scanner = new Scanner(store.getFile()); //skip the type line scanner.nextLine(); } catch (IOException ex) { throw new DataStoreException(ex); } final List<AttributeType> atts = new ArrayList<>(); for (PropertyType pt : featureType.getProperties(true)) { if (AttributeConvention.contains(pt.getName()) || pt instanceof Operation) continue; atts.add((AttributeType) pt); } this.atts = atts.toArray(new AttributeType[0]); } @Override public FeatureType getFeatureType() { return featureType; } @Override public Feature next() throws FeatureStoreRuntimeException { read(); final Feature ob = current; current = null; if (ob == null) { throw new FeatureStoreRuntimeException("No more records."); } return ob; } @Override public boolean hasNext() throws FeatureStoreRuntimeException { read(); return current != null; } private void read() throws FeatureStoreRuntimeException { if (current != null) { return; } final String line = CSVUtils.getNextLine(scanner); if (line != null) { final List<String> fields = CSVUtils.toStringList(scanner, line, store.getSeparator()); current = null; if (reuse == null) { current = CSVUtils.defaultFeature(featureType, Integer.toString(inc++)); } else { reuse.setPropertyValue(AttributeConvention.IDENTIFIER_PROPERTY.toString(), Integer.toString(inc++)); current = reuse; } final int fieldSize = fields.size(); for (int i = 0, n = atts.length; i < n; i++) { final AttributeType<?> att = atts[i]; final Object value; if (i >= fieldSize) { value = null; } else if (AttributeConvention.isGeometryAttribute(att)) { if (fields.get(i).trim().isEmpty()) { value = null; } else { try { value = reader.read(fields.get(i)); } catch (ParseException ex) { throw new FeatureStoreRuntimeException(ex); } } } else { value = ObjectConverters.convert(fields.get(i), att.getValueClass()); } current.setPropertyValue(att.getName().toString(), value); } } } @Override public void close() { fileLock.readLock().unlock(); scanner.close(); } @Override public void remove() { throw new FeatureStoreRuntimeException("Not supported on reader."); } }