/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
*
* 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.spatialite;
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Map;
import org.apache.commons.dbcp.BasicDataSource;
import org.geotools.jdbc.JDBCDataStore;
import org.geotools.jdbc.JDBCDataStoreFactory;
import org.geotools.jdbc.SQLDialect;
import org.sqlite.SQLiteConfig;
/**
* DataStoreFactory for SpatiaLite database.
*
* @author Justin Deoliveira, OpenGeo
*
*
*
* @source $URL$
*/
public class SpatiaLiteDataStoreFactory extends JDBCDataStoreFactory {
/** parameter for database type */
public static final Param DBTYPE = new Param("dbtype", String.class, "Type", true, "spatialite");
/** optional user parameter */
public static final Param USER = new Param(JDBCDataStoreFactory.USER.key, JDBCDataStoreFactory.USER.type,
JDBCDataStoreFactory.USER.description, false, JDBCDataStoreFactory.USER.sample);
/**
* base location to store sqlite database files
*/
File baseDirectory = null;
/**
* Sets the base location to store sqlite database files.
*
* @param baseDirectory A directory.
*/
public void setBaseDirectory(File baseDirectory) {
this.baseDirectory = baseDirectory;
}
/**
* The base location to store sqlite database files.
*/
public File getBaseDirectory() {
return baseDirectory;
}
@Override
protected SQLDialect createSQLDialect(JDBCDataStore dataStore) {
return new SpatiaLiteDialect( dataStore );
}
@Override
protected String getDatabaseID() {
return "spatialite";
}
@Override
protected String getDriverClassName() {
return "org.sqlite.JDBC";
}
public String getDescription() {
return "SpatiaLite";
}
@Override
protected String getValidationQuery() {
return null;
}
@Override
protected void setupParameters(Map parameters) {
super.setupParameters(parameters);
//remove unneccessary parameters
parameters.remove(HOST.key);
parameters.remove(PORT.key);
//remove user and password temporarily in order to make username optional
parameters.remove(JDBCDataStoreFactory.USER.key);
parameters.put(USER.key, USER);
//add user
//add additional parameters
parameters.put(DBTYPE.key, DBTYPE);
}
@Override
protected String getJDBCUrl(Map params) throws IOException {
String db = (String) DATABASE.lookUp(params);
String location = db;
if (baseDirectory != null) {
//prepend base directory unless it is an absolute path
if (!new File(location).isAbsolute()) {
location = baseDirectory.getAbsolutePath() + File.separator + db;
}
}
return "jdbc:sqlite:" + location;
}
@Override
public BasicDataSource createDataSource(Map params) throws IOException {
//create a datasource
BasicDataSource dataSource = new BasicDataSource();
// driver
dataSource.setDriverClassName(getDriverClassName());
// url
dataSource.setUrl(getJDBCUrl(params));
addConnectionProperties(dataSource);
initializeDataSource(dataSource);
return dataSource;
}
static void addConnectionProperties(BasicDataSource dataSource) {
SQLiteConfig config = new SQLiteConfig();
config.setSharedCache(true);
config.enableLoadExtension(true);
config.enableSpatiaLite(true);
for (Map.Entry e : config.toProperties().entrySet()) {
dataSource.addConnectionProperty((String)e.getKey(), (String)e.getValue());
}
}
static void initializeDataSource(BasicDataSource dataSource) throws IOException {
//because of the way spatialite is loaded we need to instantiate and close
// a connection, and the spatialite functions will be registered for all future
// connections
try {
Connection cx = dataSource.getConnection();
cx.close();
}
catch (SQLException e) {
throw (IOException) new IOException().initCause(e);
}
}
}