001: //$Id: ProxoolConnectionProvider.java 6463 2005-04-19 15:39:07Z steveebersole $
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.Properties;
008:
009: import org.hibernate.HibernateException;
010: import org.hibernate.cfg.Environment;
011: import org.hibernate.util.PropertiesHelper;
012: import org.hibernate.util.StringHelper;
013: import org.hibernate.util.ConfigHelper;
014:
015: import org.apache.commons.logging.Log;
016: import org.apache.commons.logging.LogFactory;
017:
018: import org.logicalcobwebs.proxool.ProxoolException;
019: import org.logicalcobwebs.proxool.ProxoolFacade;
020: import org.logicalcobwebs.proxool.configuration.JAXPConfigurator;
021: import org.logicalcobwebs.proxool.configuration.PropertyConfigurator;
022:
023: /**
024: * A connection provider that uses a Proxool connection pool. Hibernate will use this by
025: * default if the <tt>hibernate.proxool.*</tt> properties are set.
026: * @see ConnectionProvider
027: */
028: public class ProxoolConnectionProvider implements ConnectionProvider {
029:
030: private static final String PROXOOL_JDBC_STEM = "proxool.";
031:
032: private static final Log log = LogFactory
033: .getLog(ProxoolConnectionProvider.class);
034:
035: private String proxoolAlias;
036:
037: // TRUE if the pool is borrowed from the outside, FALSE if we used to create it
038: private boolean existingPool;
039:
040: // Not null if the Isolation level has been specified in the configuration file.
041: // Otherwise, it is left to the Driver's default value.
042: private Integer isolation;
043:
044: private boolean autocommit;
045:
046: /**
047: * Grab a connection
048: * @return a JDBC connection
049: * @throws SQLException
050: */
051: public Connection getConnection() throws SQLException {
052: // get a connection from the pool (thru DriverManager, cfr. Proxool doc)
053: Connection c = DriverManager.getConnection(proxoolAlias);
054:
055: // set the Transaction Isolation if defined
056: if (isolation != null)
057: c.setTransactionIsolation(isolation.intValue());
058:
059: // toggle autoCommit to false if set
060: if (c.getAutoCommit() != autocommit)
061: c.setAutoCommit(autocommit);
062:
063: // return the connection
064: return c;
065: }
066:
067: /**
068: * Dispose of a used connection.
069: * @param conn a JDBC connection
070: * @throws SQLException
071: */
072: public void closeConnection(Connection conn) throws SQLException {
073: conn.close();
074: }
075:
076: /**
077: * Initialize the connection provider from given properties.
078: * @param props <tt>SessionFactory</tt> properties
079: */
080: public void configure(Properties props) throws HibernateException {
081:
082: // Get the configurator files (if available)
083: String jaxpFile = props.getProperty(Environment.PROXOOL_XML);
084: String propFile = props
085: .getProperty(Environment.PROXOOL_PROPERTIES);
086: String externalConfig = props
087: .getProperty(Environment.PROXOOL_EXISTING_POOL);
088:
089: // Default the Proxool alias setting
090: proxoolAlias = props
091: .getProperty(Environment.PROXOOL_POOL_ALIAS);
092:
093: // Configured outside of Hibernate (i.e. Servlet container, or Java Bean Container
094: // already has Proxool pools running, and this provider is to just borrow one of these
095: if ("true".equals(externalConfig)) {
096:
097: // Validate that an alias name was provided to determine which pool to use
098: if (!StringHelper.isNotEmpty(proxoolAlias)) {
099: String msg = "Cannot configure Proxool Provider to use an existing in memory pool without the "
100: + Environment.PROXOOL_POOL_ALIAS
101: + " property set.";
102: log.fatal(msg);
103: throw new HibernateException(msg);
104: }
105: // Append the stem to the proxool pool alias
106: proxoolAlias = PROXOOL_JDBC_STEM + proxoolAlias;
107:
108: // Set the existing pool flag to true
109: existingPool = true;
110:
111: log
112: .info("Configuring Proxool Provider using existing pool in memory: "
113: + proxoolAlias);
114:
115: // Configured using the JAXP Configurator
116: } else if (StringHelper.isNotEmpty(jaxpFile)) {
117:
118: log
119: .info("Configuring Proxool Provider using JAXPConfigurator: "
120: + jaxpFile);
121:
122: // Validate that an alias name was provided to determine which pool to use
123: if (!StringHelper.isNotEmpty(proxoolAlias)) {
124: String msg = "Cannot configure Proxool Provider to use JAXP without the "
125: + Environment.PROXOOL_POOL_ALIAS
126: + " property set.";
127: log.fatal(msg);
128: throw new HibernateException(msg);
129: }
130:
131: try {
132: JAXPConfigurator.configure(ConfigHelper
133: .getConfigStreamReader(jaxpFile), false);
134: } catch (ProxoolException e) {
135: String msg = "Proxool Provider unable to load JAXP configurator file: "
136: + jaxpFile;
137: log.fatal(msg, e);
138: throw new HibernateException(msg, e);
139: }
140:
141: // Append the stem to the proxool pool alias
142: proxoolAlias = PROXOOL_JDBC_STEM + proxoolAlias;
143: log.info("Configuring Proxool Provider to use pool alias: "
144: + proxoolAlias);
145:
146: // Configured using the Properties File Configurator
147: } else if (StringHelper.isNotEmpty(propFile)) {
148:
149: log
150: .info("Configuring Proxool Provider using Properties File: "
151: + propFile);
152:
153: // Validate that an alias name was provided to determine which pool to use
154: if (!StringHelper.isNotEmpty(proxoolAlias)) {
155: String msg = "Cannot configure Proxool Provider to use Properties File without the "
156: + Environment.PROXOOL_POOL_ALIAS
157: + " property set.";
158: log.fatal(msg);
159: throw new HibernateException(msg);
160: }
161:
162: try {
163: PropertyConfigurator.configure(ConfigHelper
164: .getConfigProperties(propFile));
165: } catch (ProxoolException e) {
166: String msg = "Proxool Provider unable to load load Property configurator file: "
167: + propFile;
168: log.fatal(msg, e);
169: throw new HibernateException(msg, e);
170: }
171:
172: // Append the stem to the proxool pool alias
173: proxoolAlias = PROXOOL_JDBC_STEM + proxoolAlias;
174: log.info("Configuring Proxool Provider to use pool alias: "
175: + proxoolAlias);
176: }
177:
178: // Remember Isolation level
179: isolation = PropertiesHelper.getInteger(Environment.ISOLATION,
180: props);
181: if (isolation != null) {
182: log.info("JDBC isolation level: "
183: + Environment.isolationLevelToString(isolation
184: .intValue()));
185: }
186:
187: autocommit = PropertiesHelper.getBoolean(
188: Environment.AUTOCOMMIT, props);
189: log.info("autocommit mode: " + autocommit);
190: }
191:
192: /**
193: * Release all resources held by this provider. JavaDoc requires a second sentence.
194: * @throws HibernateException
195: */
196: public void close() throws HibernateException {
197:
198: // If the provider was leeching off an existing pool don't close it
199: if (existingPool) {
200: return;
201: }
202:
203: // We have created the pool ourselves, so shut it down
204: try {
205: ProxoolFacade.shutdown(0);
206: } catch (Exception e) {
207: // If you're closing down the ConnectionProvider chances are an
208: // is not a real big deal, just warn
209: log.warn("Exception occured when closing the Proxool pool",
210: e);
211: throw new HibernateException(
212: "Exception occured when closing the Proxool pool",
213: e);
214: }
215: }
216:
217: /**
218: * @see ConnectionProvider#supportsAggressiveRelease()
219: */
220: public boolean supportsAggressiveRelease() {
221: return false;
222: }
223:
224: }
|