blob: cb36af17d8860039f57c2a7eeba9c860d8232b57 [file] [log] [blame]
package org.apache.ddlutils.util;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashSet;
import java.util.Iterator;
import javax.sql.DataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ddlutils.DatabaseOperationException;
/**
* JdbcSupport is an abstract base class for objects which need to
* perform JDBC operations. It contains a number of useful methods
* for implementation inheritence..
*
* @version $Revision$
*/
public abstract class JdbcSupport
{
/** The Log to which logging calls will be made. */
private final Log _log = LogFactory.getLog(JdbcSupport.class);
/** The data source. */
private DataSource _dataSource;
/** The username for accessing the database. */
private String _username;
/** The password for accessing the database. */
private String _password;
/** The names of the currently borrowed connections (for debugging). */
private HashSet _openConnectionNames = new HashSet();
// Properties
//-------------------------------------------------------------------------
/**
* Returns the data source used for communicating with the database.
*
* @return The data source
*/
public DataSource getDataSource()
{
return _dataSource;
}
/**
* Sets the DataSource used for communicating with the database.
*
* @param dataSource The data source
*/
public void setDataSource(DataSource dataSource)
{
_dataSource = dataSource;
}
/**
* Returns the username used to access the database.
*
* @return The username
*/
public String getUsername()
{
return _username;
}
/**
* Sets the username to be used to access the database.
*
* @param username The username
*/
public void setUsername(String username)
{
_username = username;
}
/**
* Returns the password used to access the database.
*
* @return The password
*/
public String getPassword()
{
return _password;
}
/**
* Sets the password to be used to access the database.
*
* @param password The password
*/
public void setPassword(String password)
{
_password = password;
}
// Implementation methods
//-------------------------------------------------------------------------
/**
* Returns a (new) JDBC connection from the data source.
*
* @return The connection
*/
public Connection borrowConnection() throws DatabaseOperationException
{
try
{
Connection connection = null;
if (_username == null)
{
connection = getDataSource().getConnection();
}
else
{
connection = getDataSource().getConnection(_username, _password);
}
if (_log.isDebugEnabled())
{
String connName = connection.toString();
_log.debug("Borrowed connection "+connName+" from data source");
_openConnectionNames.add(connName);
}
return connection;
}
catch (SQLException ex)
{
throw new DatabaseOperationException("Could not get a connection from the datasource", ex);
}
}
/**
* Closes the given JDBC connection (returns it back to the pool if the datasource is poolable).
*
* @param connection The connection
*/
public void returnConnection(Connection connection)
{
try
{
if ((connection != null) && !connection.isClosed())
{
if (_log.isDebugEnabled())
{
String connName = connection.toString();
_openConnectionNames.remove(connName);
StringBuffer logMsg = new StringBuffer();
logMsg.append("Returning connection ");
logMsg.append(connName);
logMsg.append(" to data source.\nRemaining connections:");
if (_openConnectionNames.isEmpty())
{
logMsg.append(" None");
}
else
{
for (Iterator it = _openConnectionNames.iterator(); it.hasNext();)
{
logMsg.append("\n ");
logMsg.append(it.next().toString());
}
}
_log.debug(logMsg.toString());
}
connection.close();
}
}
catch (Exception e)
{
_log.warn("Caught exception while returning connection to pool", e);
}
}
/**
* Closes the given statement (which also closes all result sets for this statement) and the
* connection it belongs to.
*
* @param statement The statement
*/
public void closeStatement(Statement statement)
{
if (statement != null)
{
try
{
statement.close();
}
catch (Exception e)
{
_log.debug("Ignoring exception that occurred while closing statement", e);
}
}
}
}