/*
* 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.postgis;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Logger;
import javax.sql.DataSource;
import org.geotools.data.jdbc.ConnectionPool;
import org.geotools.data.jdbc.ConnectionPoolManager;
import org.geotools.data.jdbc.datasource.DataSourceFinder;
import org.geotools.data.jdbc.datasource.DataSourceUtil;
/**
* Shell for JDBC transactions of all types. This creates connections for the
* postgis datasource to make its transactions. To create a
* PostgisDataSource, create a PostgisConnectionFactory, then call
* getConnection(), and pass that connection to the PostgisDataSource
* constructor.
*
* @author Rob Hranac, Vision for New York
* @author Chris Holmes, TOPP
* @source $URL$
* @version $Id$
* @deprecated Use {@link DataSource}, {@link DataSourceUtil} and {@link DataSourceFinder} instead
* *
* @task REVISIT: connection pooling, implementing java.sql.Datasource. I
* removed the implementing because that class should be provided by the
* vendor, not a hack on top of DriverManager. The only problem is that
* we can't use the postgres one directly, because it doesn't allow you
* to set the charset, which some of our users need.
*/
public class PostgisConnectionFactory {
/** Standard logging instance */
private static final Logger LOGGER = org.geotools.util.logging.Logging.getLogger(
"org.geotools.defaultcore");
/** Creates PostGIS-specific JDBC driver class. */
private static final String DRIVER_CLASS = "org.postgresql.Driver";
/** Creates PostGIS-specific JDBC driver path. */
private static final String DRIVER_PATH = "jdbc:postgresql";
/** The full path used to connect to the database */
private String connPath;
/** The host to connect to */
private String host;
/** The database to connect to.*/
private String dbName;
/** The port to connect on.*/
private int port = -1;
/** The user to connect with */
private String user = "test";
/** The password of the user */
private String password = "test";
/** Map that contains Connection Pool Data Sources */
private static Map dataSources = new HashMap();
/**
* Constructor with all internal database driver classes, driver paths and
* database types.
*
* @param host The name or ip address of the computer where the postgis
* database is installed.
* @param port The port to connect on; 5432 is generally the postgres
* default.
* @param dbName The name of the pgsql database that holds the tables of
* the feature types that will be used by PostgisDataSource.
*/
public PostgisConnectionFactory(String host, String port, String dbName) {
this.host = host;
this.dbName = dbName;
if (port != null) {
try {
this.port = Integer.parseInt(port);
} catch (NumberFormatException nfe) {
throw new IllegalArgumentException("could not parse port " +
"to an int value");
}
}
connPath = DRIVER_PATH + "://" + host + ":" + port + "/"
+ dbName;
}
/**
* Constructor with all internal database driver classes, driver paths and
* database types.
*
* @param host The name or ip address of the computer where the postgis
* database is installed.
* @param port The port to connect on; 5432 is generally the postgres
* default.
* @param dbName The name of the pgsql database that holds the tables of
* the feature types that will be used by PostgisDataSource.
*/
public PostgisConnectionFactory(String host, int port, String dbName) {
connPath = DRIVER_PATH + "://" + host + ":" + port + "/"
+ dbName;
this.host = host;
this.dbName = dbName;
this.port = port;
}
/**
* Constructor with all internal database driver classes, driver paths and
* database types.
*
* @param connPath The driver class; should be passed from the
* database-specific subclass.
*/
//public PostgisConnectionFactory(String connPath) {
// connPath = DRIVER_PATH + "://" + connPath;
//}
/**
* Creates a database connection method to initialize a given database for
* feature extraction.
*
* @param user the name of the user connect to connect to the pgsql db.
* @param password the password for the user.
*/
public void setLogin(String user, String password) {
this.user = user;
this.password = password;
}
/**
* Creates a database connection method to initialize a given database for
* feature extraction using the set username and password.
*
* @return the sql Connection object to the database.
*
* @throws SQLException if the postgres driver could not be found
*/
public Connection getConnection() throws SQLException {
return getConnection(user, password);
}
/**
* Creates a database connection method to initialize a given database for
* feature extraction with the user and password params.
*
* @param user the name of the user connect to connect to the pgsql db.
* @param password the password for the user.
*
* @return the sql Connection object to the database.
*
* @throws SQLException if the postgis sql driver could not be found
*/
public Connection getConnection(String user, String password)
throws SQLException {
Properties props = new Properties();
props.put("user", user);
props.put("password", password);
return getConnection(props);
}
public ConnectionPool getConnectionPool(String user, String pass)
throws SQLException {
org.postgresql.jdbc2.optional.ConnectionPool poolDataSource = null;
String dbUrl = connPath;
String poolKey = dbUrl + user + pass;
LOGGER.fine("looking up pool key " + poolKey);
Object poolDS = dataSources.get(poolKey);
poolDataSource = (org.postgresql.jdbc2.optional.ConnectionPool)poolDS;
LOGGER.fine("pool is " + poolDataSource);
if (poolDataSource == null) {
poolDataSource = new org.postgresql.jdbc2.optional.ConnectionPool();
//source.setDataSourceName("Geotools Postgis");
poolDataSource.setServerName(host);
poolDataSource.setDatabaseName(dbName);
poolDataSource.setPortNumber(port);
poolDataSource.setUser(user);
poolDataSource.setPassword(pass);
//source.setMaxConnections(10);
//the source looks like this defaults to false, but we have
//assumed true (as that's how it was before pooling)
poolDataSource.setDefaultAutoCommit(true);
dataSources.put(poolKey, poolDataSource);
}
ConnectionPoolManager manager = ConnectionPoolManager.getInstance();
ConnectionPool connectionPool = manager.getConnectionPool(poolDataSource);
return connectionPool;
}
public ConnectionPool getConnectionPool() throws SQLException {
return getConnectionPool(user, password);
}
public void free(ConnectionPool connectionPool){
if (connectionPool == null) return;
if(!connectionPool.isClosed() ){
connectionPool.close();
}
ConnectionPoolManager.getInstance().free( connectionPool );
}
/**
* Creates a database connection method to initialize a given database for
* feature extraction with the given Properties.
*
* @param props Should contain at a minimum the user and password.
* Additional properties, such as charSet, can also be added.
*
* @return the sql Connection object to the database.
*
* @throws SQLException if the postgis sql driver could not be found
*/
public Connection getConnection(Properties props) throws SQLException {
// makes a new feature type bean to deal with incoming
Connection dbConnection = null;
// Instantiate the driver classes
try {
Class.forName(DRIVER_CLASS);
LOGGER.finest("getting connection at " + connPath + "with props: "
+ props);
dbConnection = DriverManager.getConnection(connPath, props);
} catch (ClassNotFoundException cnfe) {
throw new SQLException("Postgis driver was not found.");
}
return dbConnection;
}
}