Coverage Report - org.apache.commons.dbcp.PoolingDriver
 
Classes in this File Line Coverage Branch Coverage Complexity
PoolingDriver
64%
54/84
68%
15/22
1.862
PoolingDriver$PoolGuardConnectionWrapper
48%
53/110
56%
9/16
1.862
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  * 
 9  
  *      http://www.apache.org/licenses/LICENSE-2.0
 10  
  * 
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 
 18  
 package org.apache.commons.dbcp;
 19  
 
 20  
 import java.io.IOException;
 21  
 import java.io.InputStream;
 22  
 import java.sql.CallableStatement;
 23  
 import java.sql.Connection;
 24  
 import java.sql.DatabaseMetaData;
 25  
 import java.sql.Driver;
 26  
 import java.sql.DriverManager;
 27  
 import java.sql.DriverPropertyInfo;
 28  
 import java.sql.PreparedStatement;
 29  
 import java.sql.SQLException;
 30  
 import java.sql.SQLWarning;
 31  
 import java.sql.Statement;
 32  
 import java.util.HashMap;
 33  
 import java.util.Map;
 34  
 import java.util.NoSuchElementException;
 35  
 import java.util.Properties;
 36  
 import java.util.Set;
 37  
 
 38  
 import org.apache.commons.jocl.JOCLContentHandler;
 39  
 import org.apache.commons.pool.ObjectPool;
 40  
 import org.xml.sax.SAXException;
 41  
 
 42  
 
 43  
 /**
 44  
  * A {@link Driver} implementation that obtains
 45  
  * {@link Connection}s from a registered
 46  
  * {@link ObjectPool}.
 47  
  *
 48  
  * @author Rodney Waldhoff
 49  
  * @author Dirk Verbeeck
 50  
  * @version $Revision: 1023401 $ $Date: 2010-10-16 21:54:24 -0400 (Sat, 16 Oct 2010) $
 51  
  */
 52  
 public class PoolingDriver implements Driver {
 53  
     /** Register myself with the {@link DriverManager}. */
 54  
     static {
 55  
         try {
 56  2
             DriverManager.registerDriver(new PoolingDriver());
 57  0
         } catch(Exception e) {
 58  2
         }
 59  
     }
 60  
 
 61  
     /** The map of registered pools. */
 62  2
     protected static final HashMap _pools = new HashMap();
 63  
 
 64  
     /** Controls access to the underlying connection */
 65  2
     private static boolean accessToUnderlyingConnectionAllowed = false; 
 66  
 
 67  108
     public PoolingDriver() {
 68  108
     }
 69  
 
 70  
     /**
 71  
      * Returns the value of the accessToUnderlyingConnectionAllowed property.
 72  
      * 
 73  
      * @return true if access to the underlying is allowed, false otherwise.
 74  
      */
 75  
     public static synchronized boolean isAccessToUnderlyingConnectionAllowed() {
 76  80
         return accessToUnderlyingConnectionAllowed;
 77  
     }
 78  
 
 79  
     /**
 80  
      * Sets the value of the accessToUnderlyingConnectionAllowed property.
 81  
      * It controls if the PoolGuard allows access to the underlying connection.
 82  
      * (Default: false)
 83  
      * 
 84  
      * @param allow Access to the underlying connection is granted when true.
 85  
      */
 86  
     public static synchronized void setAccessToUnderlyingConnectionAllowed(boolean allow) {
 87  102
         accessToUnderlyingConnectionAllowed = allow;
 88  102
     }
 89  
 
 90  
     /**
 91  
      * WARNING: This method throws DbcpExceptions (RuntimeExceptions)
 92  
      * and will be replaced by the protected getConnectionPool method.
 93  
      * 
 94  
      * @deprecated This will be removed in a future version of DBCP.
 95  
      */
 96  
     public synchronized ObjectPool getPool(String name) {
 97  
         try {
 98  0
             return getConnectionPool(name);
 99  
         }
 100  0
         catch (Exception e) {
 101  0
             throw new DbcpException(e);
 102  
         }
 103  
     }
 104  
     
 105  
     public synchronized ObjectPool getConnectionPool(String name) throws SQLException {
 106  2978
         ObjectPool pool = (ObjectPool)(_pools.get(name));
 107  2978
         if(null == pool) {
 108  4
             InputStream in = this.getClass().getResourceAsStream(String.valueOf(name) + ".jocl");
 109  4
             if (in == null) {
 110  2
                 in = Thread.currentThread().getContextClassLoader(
 111  
                         ).getResourceAsStream(String.valueOf(name) + ".jocl");
 112  
             }
 113  4
             if(null != in) {
 114  2
                 JOCLContentHandler jocl = null;
 115  
                 try {
 116  2
                     jocl = JOCLContentHandler.parse(in);
 117  
                 }
 118  0
                 catch (SAXException e) {
 119  0
                     throw (SQLException) new SQLException("Could not parse configuration file").initCause(e);
 120  
                 }
 121  0
                 catch (IOException e) {
 122  0
                     throw (SQLException) new SQLException("Could not load configuration file").initCause(e);
 123  2
                 }
 124  2
                 if(jocl.getType(0).equals(String.class)) {
 125  0
                     pool = getPool((String)(jocl.getValue(0)));
 126  0
                     if(null != pool) {
 127  0
                         registerPool(name,pool);
 128  
                     }
 129  
                 } else {
 130  2
                     pool = ((PoolableConnectionFactory)(jocl.getValue(0))).getPool();
 131  2
                     if(null != pool) {
 132  2
                         registerPool(name,pool);
 133  
                     }
 134  
                 }
 135  2
             }
 136  
             else {
 137  2
                 throw new SQLException("Configuration file not found");
 138  
             }
 139  
         }
 140  2976
         return pool;
 141  
     }
 142  
 
 143  
     public synchronized void registerPool(String name, ObjectPool pool) {
 144  64
         _pools.put(name,pool);
 145  64
     }
 146  
 
 147  
     public synchronized void closePool(String name) throws SQLException {
 148  104
         ObjectPool pool = (ObjectPool) _pools.get(name);
 149  104
         if (pool != null) {
 150  58
             _pools.remove(name);
 151  
             try {
 152  58
                 pool.close();
 153  
             }
 154  0
             catch (Exception e) {
 155  0
                 throw (SQLException) new SQLException("Error closing pool " + name).initCause(e);
 156  58
             }
 157  
         }
 158  104
     }
 159  
     
 160  
     public synchronized String[] getPoolNames(){
 161  0
         Set names = _pools.keySet();
 162  0
         return (String[]) names.toArray(new String[names.size()]);
 163  
     }
 164  
 
 165  
     public boolean acceptsURL(String url) throws SQLException {
 166  
         try {
 167  3008
             return url.startsWith(URL_PREFIX);
 168  0
         } catch(NullPointerException e) {
 169  0
             return false;
 170  
         }
 171  
     }
 172  
 
 173  
     public Connection connect(String url, Properties info) throws SQLException {
 174  3004
         if(acceptsURL(url)) {
 175  2976
             ObjectPool pool = getConnectionPool(url.substring(URL_PREFIX_LEN));
 176  2974
             if(null == pool) {
 177  0
                 throw new SQLException("No pool found for " + url + ".");
 178  
             } else {
 179  
                 try {
 180  2974
                     Connection conn = (Connection)(pool.borrowObject());
 181  2970
                     if (conn != null) {
 182  2970
                         conn = new PoolGuardConnectionWrapper(pool, conn);
 183  
                     } 
 184  2970
                     return conn;
 185  0
                 } catch(SQLException e) {
 186  0
                     throw e;
 187  4
                 } catch(NoSuchElementException e) {
 188  4
                     throw (SQLException) new SQLException("Cannot get a connection, pool error: " + e.getMessage()).initCause(e);
 189  0
                 } catch(RuntimeException e) {
 190  0
                     throw e;
 191  0
                 } catch(Exception e) {
 192  0
                     throw (SQLException) new SQLException("Cannot get a connection, general error: " + e.getMessage()).initCause(e);
 193  
                 }
 194  
             }
 195  
         } else {
 196  28
             return null;
 197  
         }
 198  
     }
 199  
 
 200  
     /**
 201  
      * Invalidates the given connection.
 202  
      * 
 203  
      * @param conn connection to invalidate
 204  
      * @throws SQLException if the connection is not a 
 205  
      * <code>PoolGuardConnectionWrapper</code> or an error occurs invalidating
 206  
      * the connection
 207  
      * @since 1.2.2
 208  
      */
 209  
     public void invalidateConnection(Connection conn) throws SQLException {
 210  2
         if (conn instanceof PoolGuardConnectionWrapper) { // normal case
 211  2
             PoolGuardConnectionWrapper pgconn = (PoolGuardConnectionWrapper) conn;
 212  2
             ObjectPool pool = pgconn.pool;
 213  2
             Connection delegate = pgconn.delegate;
 214  
             try {
 215  2
                 pool.invalidateObject(delegate);
 216  
             } 
 217  0
             catch (Exception e) { 
 218  2
             }
 219  2
             pgconn.delegate = null;
 220  2
         }
 221  
         else {
 222  0
             throw new SQLException("Invalid connection class");
 223  
         }
 224  2
     }
 225  
 
 226  
     public int getMajorVersion() {
 227  0
         return MAJOR_VERSION;
 228  
     }
 229  
 
 230  
     public int getMinorVersion() {
 231  0
         return MINOR_VERSION;
 232  
     }
 233  
 
 234  
     public boolean jdbcCompliant() {
 235  0
         return true;
 236  
     }
 237  
 
 238  
     public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) {
 239  0
         return new DriverPropertyInfo[0];
 240  
     }
 241  
 
 242  
     /** My URL prefix */
 243  
     protected static final String URL_PREFIX = "jdbc:apache:commons:dbcp:";
 244  2
     protected static final int URL_PREFIX_LEN = URL_PREFIX.length();
 245  
 
 246  
     // version numbers
 247  
     protected static final int MAJOR_VERSION = 1;
 248  
     protected static final int MINOR_VERSION = 0;
 249  
 
 250  
     /**
 251  
      * PoolGuardConnectionWrapper is a Connection wrapper that makes sure a 
 252  
      * closed connection cannot be used anymore.
 253  
      */
 254  6
     static private class PoolGuardConnectionWrapper extends DelegatingConnection {
 255  
 
 256  
         private final ObjectPool pool;
 257  
         private Connection delegate;
 258  
     
 259  
         PoolGuardConnectionWrapper(ObjectPool pool, Connection delegate) {
 260  2970
             super(delegate);
 261  2970
             this.pool = pool;
 262  2970
             this.delegate = delegate;
 263  2970
         }
 264  
 
 265  
         protected void checkOpen() throws SQLException {
 266  2688
             if(delegate == null) {
 267  4
                 throw new SQLException("Connection is closed.");
 268  
             }
 269  2684
         }
 270  
 
 271  
         public void close() throws SQLException {
 272  5908
             if (delegate != null) {
 273  2966
                 this.delegate.close();
 274  2966
                 this.delegate = null;
 275  2966
                 super.setDelegate(null);
 276  
             }
 277  5908
         }
 278  
 
 279  
         public boolean isClosed() throws SQLException {
 280  548
             if (delegate == null) {
 281  178
                 return true;
 282  
             }
 283  370
             return delegate.isClosed();
 284  
         }
 285  
 
 286  
         public void clearWarnings() throws SQLException {
 287  0
             checkOpen();
 288  0
             delegate.clearWarnings();
 289  0
         }
 290  
 
 291  
         public void commit() throws SQLException {
 292  0
             checkOpen();
 293  0
             delegate.commit();
 294  0
         }
 295  
 
 296  
         public Statement createStatement() throws SQLException {
 297  16
             checkOpen();
 298  12
             return new DelegatingStatement(this, delegate.createStatement());
 299  
         }
 300  
 
 301  
         public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
 302  4
             checkOpen();
 303  4
             return new DelegatingStatement(this, delegate.createStatement(resultSetType, resultSetConcurrency));
 304  
         }
 305  
 
 306  
         public boolean equals(Object obj) {
 307  788
             if (delegate == null){
 308  0
                 return false;
 309  
             }
 310  788
             return delegate.equals(obj);
 311  
         }
 312  
 
 313  
         public boolean getAutoCommit() throws SQLException {
 314  12
             checkOpen();
 315  12
             return delegate.getAutoCommit();
 316  
         }
 317  
 
 318  
         public String getCatalog() throws SQLException {
 319  0
             checkOpen();
 320  0
             return delegate.getCatalog();
 321  
         }
 322  
 
 323  
         public DatabaseMetaData getMetaData() throws SQLException {
 324  0
             checkOpen();
 325  0
             return delegate.getMetaData();
 326  
         }
 327  
 
 328  
         public int getTransactionIsolation() throws SQLException {
 329  0
             checkOpen();
 330  0
             return delegate.getTransactionIsolation();
 331  
         }
 332  
 
 333  
         public Map getTypeMap() throws SQLException {
 334  0
             checkOpen();
 335  0
             return delegate.getTypeMap();
 336  
         }
 337  
 
 338  
         public SQLWarning getWarnings() throws SQLException {
 339  80
             checkOpen();
 340  80
             return delegate.getWarnings();
 341  
         }
 342  
 
 343  
         public int hashCode() {
 344  20
             if (delegate == null){
 345  0
                 return 0;
 346  
             }
 347  20
             return delegate.hashCode();
 348  
         }
 349  
 
 350  
         public boolean isReadOnly() throws SQLException {
 351  0
             checkOpen();
 352  0
             return delegate.isReadOnly();
 353  
         }
 354  
 
 355  
         public String nativeSQL(String sql) throws SQLException {
 356  0
             checkOpen();
 357  0
             return delegate.nativeSQL(sql);
 358  
         }
 359  
 
 360  
         public CallableStatement prepareCall(String sql) throws SQLException {
 361  52
             checkOpen();
 362  52
             return new DelegatingCallableStatement(this, delegate.prepareCall(sql));
 363  
         }
 364  
 
 365  
         public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
 366  4
             checkOpen();
 367  4
             return new DelegatingCallableStatement(this, delegate.prepareCall(sql, resultSetType, resultSetConcurrency));
 368  
         }
 369  
 
 370  
         public PreparedStatement prepareStatement(String sql) throws SQLException {
 371  2484
             checkOpen();
 372  2484
             return new DelegatingPreparedStatement(this, delegate.prepareStatement(sql));
 373  
         }
 374  
 
 375  
         public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
 376  8
             checkOpen();
 377  8
             return new DelegatingPreparedStatement(this, delegate.prepareStatement(sql, resultSetType, resultSetConcurrency));
 378  
         }
 379  
 
 380  
         public void rollback() throws SQLException {
 381  0
             checkOpen();
 382  0
             delegate.rollback();
 383  0
         }
 384  
 
 385  
         public void setAutoCommit(boolean autoCommit) throws SQLException {
 386  4
             checkOpen();
 387  4
             delegate.setAutoCommit(autoCommit);
 388  4
         }
 389  
 
 390  
         public void setCatalog(String catalog) throws SQLException {
 391  0
             checkOpen();
 392  0
             delegate.setCatalog(catalog);
 393  0
         }
 394  
 
 395  
         public void setReadOnly(boolean readOnly) throws SQLException {
 396  0
             checkOpen();
 397  0
             delegate.setReadOnly(readOnly);
 398  0
         }
 399  
 
 400  
         public void setTransactionIsolation(int level) throws SQLException {
 401  0
             checkOpen();
 402  0
             delegate.setTransactionIsolation(level);
 403  0
         }
 404  
 
 405  
         public void setTypeMap(Map map) throws SQLException {
 406  0
             checkOpen();
 407  0
             delegate.setTypeMap(map);
 408  0
         }
 409  
 
 410  
         public String toString() {
 411  0
             if (delegate == null){
 412  0
                 return "NULL";
 413  
             }
 414  0
             return delegate.toString();
 415  
         }
 416  
 
 417  
         public int getHoldability() throws SQLException {
 418  0
             checkOpen();
 419  0
             return delegate.getHoldability();
 420  
         }
 421  
     
 422  
         public void setHoldability(int holdability) throws SQLException {
 423  0
             checkOpen();
 424  0
             delegate.setHoldability(holdability);
 425  0
         }
 426  
 
 427  
         public java.sql.Savepoint setSavepoint() throws SQLException {
 428  0
             checkOpen();
 429  0
             return delegate.setSavepoint();
 430  
         }
 431  
 
 432  
         public java.sql.Savepoint setSavepoint(String name) throws SQLException {
 433  0
             checkOpen();
 434  0
             return delegate.setSavepoint(name);
 435  
         }
 436  
 
 437  
         public void releaseSavepoint(java.sql.Savepoint savepoint) throws SQLException {
 438  0
             checkOpen();
 439  0
             delegate.releaseSavepoint(savepoint);
 440  0
         }
 441  
 
 442  
         public void rollback(java.sql.Savepoint savepoint) throws SQLException {
 443  0
             checkOpen();
 444  0
             delegate.rollback(savepoint);
 445  0
         }
 446  
 
 447  
         public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
 448  4
             checkOpen();
 449  4
             return new DelegatingStatement(this, delegate.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability));
 450  
         }
 451  
 
 452  
         public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
 453  4
             checkOpen();
 454  4
             return new DelegatingCallableStatement(this, delegate.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability));
 455  
         }
 456  
 
 457  
         public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
 458  4
             checkOpen();
 459  4
             return new DelegatingPreparedStatement(this, delegate.prepareStatement(sql, autoGeneratedKeys));
 460  
         }
 461  
 
 462  
         public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
 463  4
             checkOpen();
 464  4
             return new DelegatingPreparedStatement(this, delegate.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability));
 465  
         }
 466  
 
 467  
         public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
 468  4
             checkOpen();
 469  4
             return new DelegatingPreparedStatement(this, delegate.prepareStatement(sql, columnIndexes));
 470  
         }
 471  
 
 472  
         public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
 473  4
             checkOpen();
 474  4
             return new DelegatingPreparedStatement(this, delegate.prepareStatement(sql, columnNames));
 475  
         }
 476  
 
 477  
         /**
 478  
          * @see org.apache.commons.dbcp.DelegatingConnection#getDelegate()
 479  
          */
 480  
         public Connection getDelegate() {
 481  0
             if (isAccessToUnderlyingConnectionAllowed()) {
 482  0
                 return super.getDelegate();
 483  
             } else {
 484  0
                 return null;
 485  
             }
 486  
         }
 487  
 
 488  
         /**
 489  
          * @see org.apache.commons.dbcp.DelegatingConnection#getInnermostDelegate()
 490  
          */
 491  
         public Connection getInnermostDelegate() {
 492  80
             if (isAccessToUnderlyingConnectionAllowed()) {
 493  80
                 return super.getInnermostDelegate();
 494  
             } else {
 495  0
                 return null;
 496  
             }
 497  
         }
 498  
     }
 499  
 }