/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (c) 2014 - 2015 Open Source Geospatial Foundation - all rights reserved
* (c) 2012 - 2014 OpenPlans
*
* 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.geotools.data.csv;
import java.awt.RenderingHints.Key;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.net.URI;
import java.net.URL;
import java.util.Collections;
import java.util.Map;
import org.apache.commons.io.FilenameUtils;
import org.geotools.data.DataStore;
import org.geotools.data.DataUtilities;
import org.geotools.data.FileDataStore;
import org.geotools.data.FileDataStoreFactorySpi;
import org.geotools.data.csv.parse.CSVAttributesOnlyStrategy;
import org.geotools.data.csv.parse.CSVLatLonStrategy;
import org.geotools.data.csv.parse.CSVSpecifiedWKTStrategy;
import org.geotools.data.csv.parse.CSVStrategy;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.feature.type.FeatureTypeFactoryImpl;
import org.geotools.util.KVP;
import com.vividsolutions.jts.geom.GeometryFactory;
public class CSVDataStoreFactory implements FileDataStoreFactorySpi {
private static final String FILE_TYPE = "csv";
public static final String[] EXTENSIONS = new String[] { "." + FILE_TYPE };
public static final Param FILE_PARAM = new Param("file", File.class, FILE_TYPE + " file", false);
public static final Param URL_PARAM = new Param("url", URL.class, FILE_TYPE + " file", false);
public static final Param NAMESPACEP = new Param("namespace", URI.class,
"uri to the namespace", false, null, new KVP(Param.LEVEL, "advanced"));
public static final Param STRATEGYP = new Param("strategy", String.class, "strategy", false);
public static final Param LATFIELDP = new Param("latField", String.class,
"Latitude field. Assumes a CSVSpecifiedLatLngStrategy", false);
public static final Param LnGFIELDP = new Param("lngField", String.class,
"Longitude field. Assumes a CSVSpecifiedLatLngStrategy", false);
public static final Param WKTP = new Param("wktField", String.class,
"WKT field. Assumes a CSVSpecifiedWKTStrategy", false);
public static final Param[] parametersInfo = new Param[] { FILE_PARAM, NAMESPACEP, STRATEGYP,
LATFIELDP, LnGFIELDP, WKTP };
@Override
public String getDisplayName() {
return FILE_TYPE.toUpperCase();
}
@Override
public String getDescription() {
return "Comma delimited text file";
}
@Override
public Param[] getParametersInfo() {
return parametersInfo;
}
private boolean canProcessExtension(String filename) {
String extension = FilenameUtils.getExtension(filename);
return FILE_TYPE.equalsIgnoreCase(extension);
}
private File fileFromParams(Map<String, Serializable> params) throws IOException {
File file = (File) FILE_PARAM.lookUp(params);
if (file != null) {
return file;
}
URL url = (URL) URL_PARAM.lookUp(params);
if (url != null) {
return DataUtilities.urlToFile(url);
}
return null;
}
@Override
public boolean canProcess(Map<String, Serializable> params) {
try {
File file = fileFromParams(params);
if (file != null) {
return canProcessExtension(file.getPath());
}
} catch (IOException e) {
}
return false;
}
@Override
public boolean isAvailable() {
try {
CSVDataStore.class.getName();
} catch (Exception e) {
return false;
}
return true;
}
@Override
public Map<Key, ?> getImplementationHints() {
return Collections.emptyMap();
}
public FileDataStore createDataStoreFromFile(File file) throws IOException {
return createDataStoreFromFile(file, null);
}
public FileDataStore createDataStoreFromFile(File file, URI namespace) throws IOException {
if (file == null) {
throw new IllegalArgumentException("Cannot create store from null file");
} else if (!file.exists()) {
throw new IllegalArgumentException("Cannot create store with file that does not exist");
}
Map<String, Serializable> noParams = Collections.emptyMap();
return createDataStoreFromFile(file, namespace, noParams);
}
@Override
public FileDataStore createDataStore(Map<String, Serializable> params) throws IOException {
File file = fileFromParams(params);
if (file == null) {
throw new IllegalArgumentException(
"Could not find file from params to create csv data store");
}
URI namespace = (URI) NAMESPACEP.lookUp(params);
return createDataStoreFromFile(file, namespace, params);
}
private FileDataStore createDataStoreFromFile(File file, URI namespace,
Map<String, Serializable> params) throws IOException {
CSVFileState csvFileState = new CSVFileState(file, namespace);
Object strategyParam = STRATEGYP.lookUp(params);
CSVStrategy csvStrategy = null;
if (strategyParam != null) {
String strategyString = strategyParam.toString();
if (strategyString.equalsIgnoreCase("guess")) {
csvStrategy = new CSVLatLonStrategy(csvFileState);
} else if (strategyString.equalsIgnoreCase("specify")) {
Object latParam = LATFIELDP.lookUp(params);
Object lngParam = LnGFIELDP.lookUp(params);
if (latParam == null || lngParam == null) {
throw new IllegalArgumentException(
"'specify' csv strategy selected, but lat/lng params both not specified");
}
csvStrategy = new CSVLatLonStrategy(csvFileState, latParam.toString(),
lngParam.toString());
} else if (strategyString.equalsIgnoreCase("wkt")) {
Object wktParam = WKTP.lookUp(params);
if (wktParam == null) {
throw new IllegalArgumentException(
"'wkt' csv strategy selected, but wktField param not specified");
}
csvStrategy = new CSVSpecifiedWKTStrategy(csvFileState, wktParam.toString());
} else {
csvStrategy = new CSVAttributesOnlyStrategy(csvFileState);
}
} else {
csvStrategy = new CSVAttributesOnlyStrategy(csvFileState);
}
CSVDataStore store = new CSVDataStore(csvFileState, csvStrategy);
if (namespace != null) {
store.setNamespaceURI(namespace.toString());
}
store.setDataStoreFactory(this);
store.setGeometryFactory(new GeometryFactory());
store.setFeatureTypeFactory(new FeatureTypeFactoryImpl());
store.setFeatureFactory(CommonFactoryFinder.getFeatureFactory(null));
return store;
}
@Override
public DataStore createNewDataStore(Map<String, Serializable> params) throws IOException {
return createDataStore(params);
}
@Override
public FileDataStore createDataStore(URL url) throws IOException {
File file = DataUtilities.urlToFile(url);
return createDataStoreFromFile(file);
}
@Override
public String[] getFileExtensions() {
return EXTENSIONS;
}
@Override
public boolean canProcess(URL url) {
return canProcessExtension(DataUtilities.urlToFile(url).toString());
}
@Override
public String getTypeName(URL url) throws IOException {
DataStore ds = createDataStore(url);
String[] names = ds.getTypeNames();
assert names.length == 1 : "Invalid number of type names for csv file store";
ds.dispose();
return names[0];
}
}