001: //$Id: DriverManagerConnectionProvider.java 7888 2005-08-12 21:22:38Z oneovthafew $
002: package org.hibernate.connection;
003:
004: import java.sql.Connection;
005: import java.sql.DriverManager;
006: import java.sql.SQLException;
007: import java.util.ArrayList;
008: import java.util.Iterator;
009: import java.util.Properties;
010:
011: import org.apache.commons.logging.Log;
012: import org.apache.commons.logging.LogFactory;
013: import org.hibernate.HibernateException;
014: import org.hibernate.cfg.Environment;
015: import org.hibernate.util.PropertiesHelper;
016: import org.hibernate.util.ReflectHelper;
017:
018: /**
019: * A connection provider that uses <tt>java.sql.DriverManager</tt>. This provider
020: * also implements a very rudimentary connection pool.
021: * @see ConnectionProvider
022: * @author Gavin King
023: */
024: public class DriverManagerConnectionProvider implements
025: ConnectionProvider {
026:
027: private String url;
028: private Properties connectionProps;
029: private Integer isolation;
030: private final ArrayList pool = new ArrayList();
031: private int poolSize;
032: private int checkedOut = 0;
033: private boolean autocommit;
034:
035: private static final Log log = LogFactory
036: .getLog(DriverManagerConnectionProvider.class);
037:
038: public void configure(Properties props) throws HibernateException {
039:
040: String driverClass = props.getProperty(Environment.DRIVER);
041:
042: poolSize = PropertiesHelper.getInt(Environment.POOL_SIZE,
043: props, 20); //default pool size 20
044: log
045: .info("Using Hibernate built-in connection pool (not for production use!)");
046: log.info("Hibernate connection pool size: " + poolSize);
047:
048: autocommit = PropertiesHelper.getBoolean(
049: Environment.AUTOCOMMIT, props);
050: log.info("autocommit mode: " + autocommit);
051:
052: isolation = PropertiesHelper.getInteger(Environment.ISOLATION,
053: props);
054: if (isolation != null)
055: log.info("JDBC isolation level: "
056: + Environment.isolationLevelToString(isolation
057: .intValue()));
058:
059: if (driverClass == null) {
060: log.warn("no JDBC Driver class was specified by property "
061: + Environment.DRIVER);
062: } else {
063: try {
064: // trying via forName() first to be as close to DriverManager's semantics
065: Class.forName(driverClass);
066: } catch (ClassNotFoundException cnfe) {
067: try {
068: ReflectHelper.classForName(driverClass);
069: } catch (ClassNotFoundException e) {
070: String msg = "JDBC Driver class not found: "
071: + driverClass;
072: log.fatal(msg, e);
073: throw new HibernateException(msg, e);
074: }
075: }
076: }
077:
078: url = props.getProperty(Environment.URL);
079: if (url == null) {
080: String msg = "JDBC URL was not specified by property "
081: + Environment.URL;
082: log.fatal(msg);
083: throw new HibernateException(msg);
084: }
085:
086: connectionProps = ConnectionProviderFactory
087: .getConnectionProperties(props);
088:
089: log.info("using driver: " + driverClass + " at URL: " + url);
090: // if debug level is enabled, then log the password, otherwise mask it
091: if (log.isDebugEnabled()) {
092: log.info("connection properties: " + connectionProps);
093: } else if (log.isInfoEnabled()) {
094: log.info("connection properties: "
095: + PropertiesHelper.maskOut(connectionProps,
096: "password"));
097: }
098:
099: }
100:
101: public Connection getConnection() throws SQLException {
102:
103: if (log.isTraceEnabled())
104: log.trace("total checked-out connections: " + checkedOut);
105:
106: synchronized (pool) {
107: if (!pool.isEmpty()) {
108: int last = pool.size() - 1;
109: if (log.isTraceEnabled()) {
110: log
111: .trace("using pooled JDBC connection, pool size: "
112: + last);
113: checkedOut++;
114: }
115: Connection pooled = (Connection) pool.remove(last);
116: if (isolation != null)
117: pooled
118: .setTransactionIsolation(isolation
119: .intValue());
120: if (pooled.getAutoCommit() != autocommit)
121: pooled.setAutoCommit(autocommit);
122: return pooled;
123: }
124: }
125:
126: log.debug("opening new JDBC connection");
127: Connection conn = DriverManager.getConnection(url,
128: connectionProps);
129: if (isolation != null)
130: conn.setTransactionIsolation(isolation.intValue());
131: if (conn.getAutoCommit() != autocommit)
132: conn.setAutoCommit(autocommit);
133:
134: if (log.isDebugEnabled()) {
135: log.debug("created connection to: " + url
136: + ", Isolation Level: "
137: + conn.getTransactionIsolation());
138: }
139: if (log.isTraceEnabled())
140: checkedOut++;
141:
142: return conn;
143: }
144:
145: public void closeConnection(Connection conn) throws SQLException {
146:
147: if (log.isDebugEnabled())
148: checkedOut--;
149:
150: synchronized (pool) {
151: int currentSize = pool.size();
152: if (currentSize < poolSize) {
153: if (log.isTraceEnabled())
154: log
155: .trace("returning connection to pool, pool size: "
156: + (currentSize + 1));
157: pool.add(conn);
158: return;
159: }
160: }
161:
162: log.debug("closing JDBC connection");
163:
164: conn.close();
165:
166: }
167:
168: protected void finalize() {
169: close();
170: }
171:
172: public void close() {
173:
174: log.info("cleaning up connection pool: " + url);
175:
176: Iterator iter = pool.iterator();
177: while (iter.hasNext()) {
178: try {
179: ((Connection) iter.next()).close();
180: } catch (SQLException sqle) {
181: log.warn("problem closing pooled connection", sqle);
182: }
183: }
184: pool.clear();
185:
186: }
187:
188: /**
189: * @see ConnectionProvider#supportsAggressiveRelease()
190: */
191: public boolean supportsAggressiveRelease() {
192: return false;
193: }
194:
195: }
|