Coverage Report - org.hibernate.connection.SimpleConnectionProvider
 
Classes in this File Line Coverage Branch Coverage Complexity
SimpleConnectionProvider
0%
0/107
0%
0/56
5.273
 
 1  
 /*
 2  
  * Hibernate, Relational Persistence for Idiomatic Java
 3  
  *
 4  
  * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
 5  
  * indicated by the @author tags or express copyright attribution
 6  
  * statements applied by the authors.  All third-party contributions are
 7  
  * distributed under license by Red Hat Middleware LLC.
 8  
  *
 9  
  * This copyrighted material is made available to anyone wishing to use, modify,
 10  
  * copy, or redistribute it subject to the terms and conditions of the GNU
 11  
  * Lesser General Public License, as published by the Free Software Foundation.
 12  
  *
 13  
  * This program is distributed in the hope that it will be useful,
 14  
  * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 15  
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
 16  
  * for more details.
 17  
  *
 18  
  * You should have received a copy of the GNU Lesser General Public License
 19  
  * along with this distribution; if not, write to:
 20  
  * Free Software Foundation, Inc.
 21  
  * 51 Franklin Street, Fifth Floor
 22  
  * Boston, MA  02110-1301  USA
 23  
  *
 24  
  */
 25  
 package org.hibernate.connection;
 26  
 
 27  
 
 28  
 import java.sql.Connection;
 29  
 import java.sql.Driver;
 30  
 import java.sql.SQLException;
 31  
 import java.util.ArrayList;
 32  
 import java.util.Iterator;
 33  
 import java.util.Map;
 34  
 import java.util.Properties;
 35  
 
 36  
 import org.hibernate.HibernateException;
 37  
 import org.hibernate.cfg.Environment;
 38  
 import org.hibernate.util.ReflectHelper;
 39  
 import org.slf4j.Logger;
 40  
 import org.slf4j.LoggerFactory;
 41  
 
 42  
 /**
 43  
  * This is the Hibernate class org.hibernate.connection.connection.DriverManagerConnectionProvider, 
 44  
  * tweaked in order to work with Mule's hot deployment.
 45  
  * 
 46  
  * A very simple connection provider which does <u>not</u> use <tt>java.sql.DriverManager</tt>. This provider
 47  
  * also implements a very rudimentary connection pool.
 48  
  * @see ConnectionProvider
 49  
  * @author Gavin King
 50  
  */
 51  0
 public class SimpleConnectionProvider implements ConnectionProvider {
 52  
 
 53  
         private String url;
 54  
         private Properties connectionProps;
 55  
         private Integer isolation;
 56  0
         private final ArrayList pool = new ArrayList();
 57  
         private int poolSize;
 58  0
         private int checkedOut = 0;
 59  
         private boolean autocommit;
 60  
         private Driver driver;
 61  
 
 62  0
         private static final Logger log = LoggerFactory.getLogger(SimpleConnectionProvider.class);
 63  
 
 64  
         public void configure(Properties props) throws HibernateException {
 65  
 
 66  0
                 String driverClass = props.getProperty(Environment.DRIVER);
 67  
 
 68  0
                 poolSize = getInt(Environment.POOL_SIZE, props, 20); //default pool size 20
 69  0
                 log.info("Using Hibernate built-in connection pool (not for production use!)");
 70  0
                 log.info("Hibernate connection pool size: " + poolSize);
 71  
                 
 72  0
                 autocommit = getBoolean(Environment.AUTOCOMMIT, props);
 73  0
                 log.info("autocommit mode: " + autocommit);
 74  
 
 75  0
                 isolation = getInteger(Environment.ISOLATION, props);
 76  0
                 if (isolation!=null)
 77  0
                 log.info( "JDBC isolation level: " + Environment.isolationLevelToString( isolation.intValue() ) );
 78  
 
 79  0
                 if (driverClass==null) {
 80  0
                         log.warn("no JDBC Driver class was specified by property " + Environment.DRIVER);
 81  
                 }
 82  
                 else {                    
 83  
                         try {
 84  
                                 // trying via forName() first to be as close to DriverManager's semantics
 85  0
                                 driver = (Driver) Class.forName(driverClass, true, Thread.currentThread().getContextClassLoader()).newInstance();
 86  
                         }
 87  0
                         catch (Exception e) {
 88  
                                 try {
 89  0
                                     driver = (Driver) ReflectHelper.classForName(driverClass).newInstance();
 90  
                                 }
 91  0
                                 catch (Exception e1) {
 92  0
                                         log.error(e1.getMessage());
 93  0
                                         throw new HibernateException(e1);
 94  0
                                 }
 95  0
                         }
 96  
                 }
 97  
 
 98  0
                 url = props.getProperty( Environment.URL );
 99  0
                 if ( url == null ) {
 100  0
                         String msg = "JDBC URL was not specified by property " + Environment.URL;
 101  0
                         log.error( msg );
 102  0
                         throw new HibernateException( msg );
 103  
                 }
 104  
 
 105  0
                 connectionProps = ConnectionProviderFactory.getConnectionProperties( props );
 106  
 
 107  0
                 log.info( "using driver: " + driverClass + " at URL: " + url );
 108  
                 // if debug level is enabled, then log the password, otherwise mask it
 109  0
                 if ( log.isDebugEnabled() ) {
 110  0
                         log.info( "connection properties: " + connectionProps );
 111  
                 } 
 112  0
                 else if ( log.isInfoEnabled() ) {
 113  0
                         log.info( "connection properties: " + maskOut(connectionProps, "password") );
 114  
                 }
 115  
 
 116  0
         }
 117  
 
 118  
         public Connection getConnection() throws SQLException {
 119  
 
 120  0
                 if ( log.isTraceEnabled() ) log.trace( "total checked-out connections: " + checkedOut );
 121  
 
 122  0
                 synchronized (pool) {
 123  0
                         if ( !pool.isEmpty() ) {
 124  0
                                 int last = pool.size() - 1;
 125  0
                                 if ( log.isTraceEnabled() ) {
 126  0
                                         log.trace("using pooled JDBC connection, pool size: " + last);
 127  0
                                         checkedOut++;
 128  
                                 }
 129  0
                                 Connection pooled = (Connection) pool.remove(last);
 130  0
                                 if (isolation!=null) pooled.setTransactionIsolation( isolation.intValue() );
 131  0
                                 if ( pooled.getAutoCommit()!=autocommit ) pooled.setAutoCommit(autocommit);
 132  0
                                 return pooled;
 133  
                         }
 134  0
                 }
 135  
 
 136  0
         log.debug("opening new JDBC connection");
 137  0
                 Connection conn = driver.connect(url, connectionProps);
 138  0
                 if (isolation!=null) conn.setTransactionIsolation( isolation.intValue() );
 139  0
                 if ( conn.getAutoCommit()!=autocommit ) conn.setAutoCommit(autocommit);
 140  
 
 141  0
                 if ( log.isDebugEnabled() ) {
 142  0
                         log.debug( "created connection to: " + url + ", Isolation Level: " + conn.getTransactionIsolation() );
 143  
                 }
 144  0
                 if ( log.isTraceEnabled() ) checkedOut++;
 145  
 
 146  0
                 return conn;
 147  
         }
 148  
 
 149  
         public void closeConnection(Connection conn) throws SQLException {
 150  
 
 151  0
                 if ( log.isDebugEnabled() ) checkedOut--;
 152  
 
 153  0
                 synchronized (pool) {
 154  0
                         int currentSize = pool.size();
 155  0
                         if ( currentSize < poolSize ) {
 156  0
                                 if ( log.isTraceEnabled() ) log.trace("returning connection to pool, pool size: " + (currentSize + 1) );
 157  0
                                 pool.add(conn);
 158  0
                                 return;
 159  
                         }
 160  0
                 }
 161  
 
 162  0
                 log.debug("closing JDBC connection");
 163  
 
 164  0
                 conn.close();
 165  
 
 166  0
         }
 167  
 
 168  
         protected void finalize() {
 169  0
                 close();
 170  0
         }
 171  
 
 172  
         public void close() {
 173  
 
 174  0
                 log.info("cleaning up connection pool: " + url);
 175  
 
 176  0
                 Iterator iter = pool.iterator();
 177  0
                 while ( iter.hasNext() ) {
 178  
                         try {
 179  0
                                 ( (Connection) iter.next() ).close();
 180  
                         }
 181  0
                         catch (SQLException sqle) {
 182  0
                                 log.warn("problem closing pooled connection", sqle);
 183  0
                         }
 184  
                 }
 185  0
                 pool.clear();
 186  
 
 187  0
         }
 188  
 
 189  
         /**
 190  
          * @see ConnectionProvider#supportsAggressiveRelease()
 191  
          */
 192  
         public boolean supportsAggressiveRelease() {
 193  0
                 return false;
 194  
         }
 195  
         
 196  
         //////////////////////////////////////////////////////////////////////////
 197  
         // The following utility methods are copied from ConfigurationHelper.java
 198  
     //////////////////////////////////////////////////////////////////////////
 199  
         
 200  
     /**
 201  
      * Get the config value as a boolean (default of false)
 202  
      *
 203  
      * @param name The config setting name.
 204  
      * @param values The map of config values
 205  
      *
 206  
      * @return The value.
 207  
      */
 208  
     public static boolean getBoolean(String name, Map values) {
 209  0
         return getBoolean( name, values, false );
 210  
     }
 211  
 
 212  
     /**
 213  
      * Get the config value as a boolean.
 214  
      *
 215  
      * @param name The config setting name.
 216  
      * @param values The map of config values
 217  
      * @param defaultValue The default value to use if not found
 218  
      *
 219  
      * @return The value.
 220  
      */
 221  
     public static boolean getBoolean(String name, Map values, boolean defaultValue) {
 222  0
         Object value = values.get( name );
 223  0
         if ( value == null ) {
 224  0
             return defaultValue;
 225  
         }
 226  0
         if ( Boolean.class.isInstance( value ) ) {
 227  0
             return ( (Boolean) value ).booleanValue();
 228  
         }
 229  0
         if ( String.class.isInstance( value ) ) {
 230  0
             return Boolean.parseBoolean( (String) value );
 231  
         }
 232  0
         throw new HibernateException(
 233  
                 "Could not determine how to handle configuration value [name=" + name + ", value=" + value + "] as boolean"
 234  
         );
 235  
     }
 236  
 
 237  
     /**
 238  
      * Get the config value as an int
 239  
      *
 240  
      * @param name The config setting name.
 241  
      * @param values The map of config values
 242  
      * @param defaultValue The default value to use if not found
 243  
      *
 244  
      * @return The value.
 245  
      */
 246  
     public static int getInt(String name, Map values, int defaultValue) {
 247  0
         Object value = values.get( name );
 248  0
         if ( value == null ) {
 249  0
             return defaultValue;
 250  
         }
 251  0
         if ( Integer.class.isInstance( value ) ) {
 252  0
             return ( (Integer) value ).intValue();
 253  
         }
 254  0
         if ( String.class.isInstance( value ) ) {
 255  0
             return Integer.parseInt( (String) value );
 256  
         }
 257  0
         throw new HibernateException(
 258  
                 "Could not determine how to handle configuration value [name=" + name +
 259  
                         ", value=" + value + "(" + value.getClass().getName() + ")] as int"
 260  
         );
 261  
     }
 262  
 
 263  
     /**
 264  
      * Get the config value as an {@link Integer}
 265  
      *
 266  
      * @param name The config setting name.
 267  
      * @param values The map of config values
 268  
      *
 269  
      * @return The value, or null if not found
 270  
      */
 271  
     public static Integer getInteger(String name, Map values) {
 272  0
         Object value = values.get( name );
 273  0
         if ( value == null ) {
 274  0
             return null;
 275  
         }
 276  0
         if ( Integer.class.isInstance( value ) ) {
 277  0
             return (Integer) value;
 278  
         }
 279  0
         if ( String.class.isInstance( value ) ) {
 280  0
             return Integer.valueOf( (String) value );
 281  
         }
 282  0
         throw new HibernateException(
 283  
                 "Could not determine how to handle configuration value [name=" + name +
 284  
                         ", value=" + value + "(" + value.getClass().getName() + ")] as Integer"
 285  
         );
 286  
     }
 287  
 
 288  
     /**
 289  
      * replace a property by a starred version
 290  
      *
 291  
      * @param props properties to check
 292  
      * @param key proeprty to mask
 293  
      *
 294  
      * @return cloned and masked properties
 295  
      */
 296  
     public static Properties maskOut(Properties props, String key) {
 297  0
         Properties clone = ( Properties ) props.clone();
 298  0
         if ( clone.get( key ) != null ) {
 299  0
             clone.setProperty( key, "****" );
 300  
         }
 301  0
         return clone;
 302  
     }        
 303  
 }
 304  
 
 305  
 
 306  
 
 307  
 
 308  
 
 309  
 
 310