Coverage Report - org.apache.commons.dbcp.DelegatingConnection
 
Classes in this File Line Coverage Branch Coverage Complexity
DelegatingConnection
51%
128/247
69%
39/56
2.906
 
 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.sql.CallableStatement;
 21  
 import java.sql.Connection;
 22  
 import java.sql.DatabaseMetaData;
 23  
 import java.sql.PreparedStatement;
 24  
 import java.sql.SQLException;
 25  
 import java.sql.SQLWarning;
 26  
 import java.sql.Statement;
 27  
 import java.util.Iterator;
 28  
 import java.util.List;
 29  
 import java.util.Map;
 30  
 import java.sql.ResultSet;
 31  
 /* JDBC_4_ANT_KEY_BEGIN */
 32  
 import java.sql.Array;
 33  
 import java.sql.Blob;
 34  
 import java.sql.ClientInfoStatus;
 35  
 import java.sql.Clob;
 36  
 import java.sql.NClob;
 37  
 import java.sql.SQLClientInfoException;
 38  
 import java.sql.SQLXML;
 39  
 import java.sql.Struct;
 40  
 import java.util.Collections;
 41  
 import java.util.Properties;
 42  
 /* JDBC_4_ANT_KEY_END */
 43  
 
 44  
 /**
 45  
  * A base delegating implementation of {@link Connection}.
 46  
  * <p>
 47  
  * All of the methods from the {@link Connection} interface
 48  
  * simply check to see that the {@link Connection} is active,
 49  
  * and call the corresponding method on the "delegate"
 50  
  * provided in my constructor.
 51  
  * <p>
 52  
  * Extends AbandonedTrace to implement Connection tracking and
 53  
  * logging of code which created the Connection. Tracking the
 54  
  * Connection ensures that the AbandonedObjectPool can close
 55  
  * this connection and recycle it if its pool of connections
 56  
  * is nearing exhaustion and this connection's last usage is
 57  
  * older than the removeAbandonedTimeout.
 58  
  *
 59  
  * @author Rodney Waldhoff
 60  
  * @author Glenn L. Nielsen
 61  
  * @author James House
 62  
  * @author Dirk Verbeeck
 63  
  * @version $Revision: 1023401 $ $Date: 2010-10-16 21:54:24 -0400 (Sat, 16 Oct 2010) $
 64  
  */
 65  
 public class DelegatingConnection extends AbandonedTrace
 66  
         implements Connection {
 67  
 
 68  
 /* JDBC_4_ANT_KEY_BEGIN */
 69  2
     private static final Map<String, ClientInfoStatus> EMPTY_FAILED_PROPERTIES =
 70  
         Collections.<String, ClientInfoStatus>emptyMap();
 71  
 /* JDBC_4_ANT_KEY_END */
 72  
 
 73  
     /** My delegate {@link Connection}. */
 74  25082
     protected Connection _conn = null;
 75  
 
 76  25082
     protected boolean _closed = false;
 77  
     
 78  
     /**
 79  
      * Create a wrapper for the Connection which traces this
 80  
      * Connection in the AbandonedObjectPool.
 81  
      *
 82  
      * @param c the {@link Connection} to delegate all calls to.
 83  
      */
 84  
     public DelegatingConnection(Connection c) {
 85  22870
         super();
 86  22870
         _conn = c;
 87  22870
     }
 88  
 
 89  
     /**
 90  
      * Create a wrapper for the Connection which traces
 91  
      * the Statements created so that any unclosed Statements
 92  
      * can be closed when this Connection is closed.
 93  
      *
 94  
      * @param c the {@link Connection} to delegate all calls to.
 95  
      * @param config the configuration for tracing abandoned objects
 96  
      */
 97  
     public DelegatingConnection(Connection c, AbandonedConfig config) {
 98  2212
         super(config);
 99  2212
         _conn = c;
 100  2212
     }
 101  
 
 102  
     /**
 103  
      * Returns a string representation of the metadata associated with
 104  
      * the innnermost delegate connection.
 105  
      * 
 106  
      * @since 1.2.2
 107  
      */
 108  
     public String toString() {
 109  10
         String s = null;
 110  
         
 111  10
         Connection c = this.getInnermostDelegateInternal();
 112  10
         if (c != null) {
 113  
             try {
 114  10
                 if (c.isClosed()) {
 115  2
                     s = "connection is closed";
 116  
                 }
 117  
                 else {
 118  8
                     DatabaseMetaData meta = c.getMetaData();
 119  8
                     if (meta != null) {
 120  8
                         StringBuffer sb = new StringBuffer();
 121  8
                         sb.append(meta.getURL());
 122  8
                         sb.append(", UserName=");
 123  8
                         sb.append(meta.getUserName());
 124  8
                         sb.append(", ");
 125  8
                         sb.append(meta.getDriverName());
 126  8
                         s = sb.toString();
 127  
                     }
 128  
                 }
 129  
             }
 130  0
             catch (SQLException ex) {
 131  
                 // Ignore
 132  10
             }
 133  
         }
 134  
         
 135  10
         if (s == null) {
 136  0
             s = super.toString();
 137  
         }
 138  
         
 139  10
         return s;
 140  
     }
 141  
 
 142  
     /**
 143  
      * Returns my underlying {@link Connection}.
 144  
      * @return my underlying {@link Connection}.
 145  
      */
 146  
     public Connection getDelegate() {
 147  242
         return getDelegateInternal();
 148  
     }
 149  
     
 150  
     /**
 151  
      * Should be final but can't be for compatibility with previous releases.
 152  
      */
 153  
     protected Connection getDelegateInternal() {
 154  16578
         return _conn;
 155  
     }
 156  
     
 157  
     /**
 158  
      * Compares innermost delegate to the given connection.
 159  
      * 
 160  
      * @param c connection to compare innermost delegate with
 161  
      * @return true if innermost delegate equals <code>c</code>
 162  
      * @since 1.2.2
 163  
      */
 164  
     public boolean innermostDelegateEquals(Connection c) {
 165  2914
         Connection innerCon = getInnermostDelegateInternal();
 166  2914
         if (innerCon == null) {
 167  2
             return c == null;
 168  
         } else {
 169  2912
             return innerCon.equals(c);
 170  
         }
 171  
     }
 172  
 
 173  
     /**
 174  
      * This method considers two objects to be equal 
 175  
      * if the underlying jdbc objects are equal.
 176  
      */
 177  
     public boolean equals(Object obj) {
 178  4868
         if (obj == null) {
 179  6
             return false;
 180  
         }
 181  4862
         if (obj == this) {
 182  1568
             return true;
 183  
         }
 184  3294
         Connection delegate = getInnermostDelegateInternal();
 185  3294
         if (delegate == null) {
 186  0
             return false;
 187  
         }
 188  3294
         if (obj instanceof DelegatingConnection) {    
 189  2880
             DelegatingConnection c = (DelegatingConnection) obj;
 190  2880
             return c.innermostDelegateEquals(delegate);
 191  
         }
 192  
         else {
 193  414
             return delegate.equals(obj);
 194  
         }
 195  
     }
 196  
 
 197  
     public int hashCode() {
 198  526
         Object obj = getInnermostDelegateInternal();
 199  526
         if (obj == null) {
 200  0
             return 0;
 201  
         }
 202  526
         return obj.hashCode();
 203  
     }
 204  
 
 205  
 
 206  
     /**
 207  
      * If my underlying {@link Connection} is not a
 208  
      * <tt>DelegatingConnection</tt>, returns it,
 209  
      * otherwise recursively invokes this method on
 210  
      * my delegate.
 211  
      * <p>
 212  
      * Hence this method will return the first
 213  
      * delegate that is not a <tt>DelegatingConnection</tt>,
 214  
      * or <tt>null</tt> when no non-<tt>DelegatingConnection</tt>
 215  
      * delegate can be found by traversing this chain.
 216  
      * <p>
 217  
      * This method is useful when you may have nested
 218  
      * <tt>DelegatingConnection</tt>s, and you want to make
 219  
      * sure to obtain a "genuine" {@link Connection}.
 220  
      */
 221  
     public Connection getInnermostDelegate() {
 222  1555
         return getInnermostDelegateInternal();
 223  
     }
 224  
 
 225  
     protected final Connection getInnermostDelegateInternal() {
 226  13110
         Connection c = _conn;
 227  16492
         while(c != null && c instanceof DelegatingConnection) {
 228  3382
             c = ((DelegatingConnection)c).getDelegateInternal();
 229  3382
             if(this == c) {
 230  0
                 return null;
 231  
             }
 232  
         }
 233  13110
         return c;
 234  
     }
 235  
     
 236  
     /** Sets my delegate. */
 237  
     public void setDelegate(Connection c) {
 238  14496
         _conn = c;
 239  14496
     }
 240  
 
 241  
     /**
 242  
      * Closes the underlying connection, and close
 243  
      * any Statements that were not explicitly closed.
 244  
      */
 245  
     public void close() throws SQLException {
 246  2122
         passivate();
 247  2122
         _conn.close();
 248  2112
     }
 249  
 
 250  
     protected void handleException(SQLException e) throws SQLException {
 251  936
         throw e;
 252  
     }
 253  
 
 254  
     public Statement createStatement() throws SQLException {
 255  19924
         checkOpen();
 256  
         try {
 257  19914
             return new DelegatingStatement(this, _conn.createStatement());
 258  
         }
 259  0
         catch (SQLException e) {
 260  0
             handleException(e);
 261  0
             return null;
 262  
         }
 263  
     }
 264  
 
 265  
     public Statement createStatement(int resultSetType,
 266  
                                      int resultSetConcurrency) throws SQLException {
 267  30
         checkOpen();
 268  
         try {
 269  30
             return new DelegatingStatement
 270  
                 (this, _conn.createStatement(resultSetType,resultSetConcurrency));
 271  
         }
 272  0
         catch (SQLException e) {
 273  0
             handleException(e);
 274  0
             return null;
 275  
         }
 276  
     }
 277  
 
 278  
     public PreparedStatement prepareStatement(String sql) throws SQLException {
 279  14954
         checkOpen();
 280  
         try {
 281  14952
             return new DelegatingPreparedStatement
 282  
                 (this, _conn.prepareStatement(sql));
 283  
         }
 284  4
         catch (SQLException e) {
 285  4
             handleException(e);
 286  0
             return null;
 287  
         }
 288  
     }
 289  
 
 290  
     public PreparedStatement prepareStatement(String sql,
 291  
                                               int resultSetType,
 292  
                                               int resultSetConcurrency) throws SQLException {
 293  48
         checkOpen();
 294  
         try {
 295  48
             return new DelegatingPreparedStatement
 296  
                 (this, _conn.prepareStatement
 297  
                     (sql,resultSetType,resultSetConcurrency));
 298  
         }
 299  0
         catch (SQLException e) {
 300  0
             handleException(e);
 301  0
             return null;
 302  
         }
 303  
     }
 304  
 
 305  
     public CallableStatement prepareCall(String sql) throws SQLException {
 306  336
         checkOpen();
 307  
         try {
 308  336
             return new DelegatingCallableStatement(this, _conn.prepareCall(sql));
 309  
         }
 310  0
         catch (SQLException e) {
 311  0
             handleException(e);
 312  0
             return null;
 313  
         }
 314  
     }
 315  
 
 316  
     public CallableStatement prepareCall(String sql,
 317  
                                          int resultSetType,
 318  
                                          int resultSetConcurrency) throws SQLException {
 319  24
         checkOpen();
 320  
         try {
 321  24
             return new DelegatingCallableStatement
 322  
                 (this, _conn.prepareCall(sql, resultSetType,resultSetConcurrency));
 323  
         }
 324  0
         catch (SQLException e) {
 325  0
             handleException(e);
 326  0
             return null;
 327  
         }
 328  
     }
 329  
 
 330  
     public void clearWarnings() throws SQLException
 331  25797
     { checkOpen(); try { _conn.clearWarnings(); } catch (SQLException e) { handleException(e); } }
 332  
     
 333  
     public void commit() throws SQLException
 334  0
     { checkOpen(); try { _conn.commit(); } catch (SQLException e) { handleException(e); } }
 335  
     
 336  
     public boolean getAutoCommit() throws SQLException
 337  62219
     { checkOpen(); try { return _conn.getAutoCommit(); } catch (SQLException e) { handleException(e); return false; } 
 338  
     }
 339  
     public String getCatalog() throws SQLException
 340  12236
     { checkOpen(); try { return _conn.getCatalog(); } catch (SQLException e) { handleException(e); return null; } }
 341  
     
 342  
     public DatabaseMetaData getMetaData() throws SQLException {
 343  4
         checkOpen();
 344  
         try {
 345  4
             return new DelegatingDatabaseMetaData(this, _conn.getMetaData());
 346  0
         } catch (SQLException e) {
 347  0
             handleException(e);
 348  0
             return null;
 349  
         }
 350  
     }
 351  
     
 352  
     public int getTransactionIsolation() throws SQLException
 353  8172
     { checkOpen(); try { return _conn.getTransactionIsolation(); } catch (SQLException e) { handleException(e); return -1; } }
 354  
     
 355  
     public Map getTypeMap() throws SQLException
 356  0
     { checkOpen(); try { return _conn.getTypeMap(); } catch (SQLException e) { handleException(e); return null; } }
 357  
     
 358  
     public SQLWarning getWarnings() throws SQLException
 359  616
     { checkOpen(); try { return _conn.getWarnings(); } catch (SQLException e) { handleException(e); return null; } }
 360  
     
 361  
     public boolean isReadOnly() throws SQLException
 362  25877
     { checkOpen(); try { return _conn.isReadOnly(); } catch (SQLException e) { handleException(e); return false; } }
 363  
     
 364  
     public String nativeSQL(String sql) throws SQLException
 365  0
     { checkOpen(); try { return _conn.nativeSQL(sql); } catch (SQLException e) { handleException(e); return null; } }
 366  
     
 367  
     public void rollback() throws SQLException
 368  38
     { checkOpen(); try {  _conn.rollback(); } catch (SQLException e) { handleException(e); } }
 369  
     
 370  
     public void setAutoCommit(boolean autoCommit) throws SQLException
 371  140
     { checkOpen(); try { _conn.setAutoCommit(autoCommit); } catch (SQLException e) { handleException(e); } }
 372  
 
 373  
     public void setCatalog(String catalog) throws SQLException
 374  1852
     { checkOpen(); try { _conn.setCatalog(catalog); } catch (SQLException e) { handleException(e); } }
 375  
 
 376  
     public void setReadOnly(boolean readOnly) throws SQLException
 377  577
     { checkOpen(); try { _conn.setReadOnly(readOnly); } catch (SQLException e) { handleException(e); } }
 378  
 
 379  
     public void setTransactionIsolation(int level) throws SQLException
 380  9307
     { checkOpen(); try { _conn.setTransactionIsolation(level); } catch (SQLException e) { handleException(e); } }
 381  
 
 382  
     public void setTypeMap(Map map) throws SQLException
 383  0
     { checkOpen(); try { _conn.setTypeMap(map); } catch (SQLException e) { handleException(e); } }
 384  
 
 385  
     public boolean isClosed() throws SQLException {
 386  35051
         return _closed || _conn.isClosed();
 387  
     }
 388  
 
 389  
     protected void checkOpen() throws SQLException {
 390  189454
         if(_closed) {
 391  20
             if (null != _conn) {
 392  18
                 String label = "";
 393  
                 try {
 394  18
                     label = _conn.toString();
 395  2
                 } catch (Exception ex) {
 396  
                     // ignore, leave label empty
 397  16
                 }
 398  18
                 throw new SQLException
 399  
                     ("Connection " + label + " is closed.");
 400  
             } else {
 401  2
                 throw new SQLException
 402  
                     ("Connection is null.");
 403  
             }      
 404  
         }
 405  189434
     }
 406  
 
 407  
     protected void activate() {
 408  18152
         _closed = false;
 409  18152
         setLastUsed();
 410  18152
         if(_conn instanceof DelegatingConnection) {
 411  4564
             ((DelegatingConnection)_conn).activate();
 412  
         }
 413  18152
     }
 414  
 
 415  
     protected void passivate() throws SQLException {
 416  
         try {
 417  
             // The JDBC spec requires that a Connection close any open
 418  
             // Statement's when it is closed.
 419  
             // DBCP-288. Not all the traced objects will be statements
 420  28516
             List traces = getTrace();
 421  28516
             if(traces != null) {
 422  28516
                 Iterator traceIter = traces.iterator();
 423  28994
                 while (traceIter.hasNext()) {
 424  478
                     Object trace = traceIter.next();
 425  478
                     if (trace instanceof Statement) {
 426  474
                         ((Statement) trace).close();
 427  4
                     } else if (trace instanceof ResultSet) {
 428  
                         // DBCP-265: Need to close the result sets that are
 429  
                         // generated via DatabaseMetaData
 430  2
                         ((ResultSet) trace).close();
 431  
                     }
 432  478
                 }
 433  28516
                 clearTrace();
 434  
             }
 435  28516
             setLastUsed(0);
 436  28516
             if(_conn instanceof DelegatingConnection) {
 437  5087
                 ((DelegatingConnection)_conn).passivate();
 438  
             }
 439  
         }
 440  
         finally {
 441  28516
             _closed = true;
 442  28516
         }
 443  28516
     }
 444  
 
 445  
     public int getHoldability() throws SQLException
 446  0
     { checkOpen(); try { return _conn.getHoldability(); } catch (SQLException e) { handleException(e); return 0; } }
 447  
 
 448  
     public void setHoldability(int holdability) throws SQLException
 449  0
     { checkOpen(); try { _conn.setHoldability(holdability); } catch (SQLException e) { handleException(e); } }
 450  
 
 451  
     public java.sql.Savepoint setSavepoint() throws SQLException
 452  0
     { checkOpen(); try { return _conn.setSavepoint(); } catch (SQLException e) { handleException(e); return null; } }
 453  
 
 454  
     public java.sql.Savepoint setSavepoint(String name) throws SQLException
 455  0
     { checkOpen(); try { return _conn.setSavepoint(name); } catch (SQLException e) { handleException(e); return null; } }
 456  
 
 457  
     public void rollback(java.sql.Savepoint savepoint) throws SQLException
 458  0
     { checkOpen(); try { _conn.rollback(savepoint); } catch (SQLException e) { handleException(e); } }
 459  
 
 460  
     public void releaseSavepoint(java.sql.Savepoint savepoint) throws SQLException
 461  0
     { checkOpen(); try { _conn.releaseSavepoint(savepoint); } catch (SQLException e) { handleException(e); } }
 462  
 
 463  
     public Statement createStatement(int resultSetType,
 464  
                                      int resultSetConcurrency,
 465  
                                      int resultSetHoldability) throws SQLException {
 466  30
         checkOpen();
 467  
         try {
 468  30
             return new DelegatingStatement(this, _conn.createStatement(
 469  
                 resultSetType, resultSetConcurrency, resultSetHoldability));
 470  
         }
 471  0
         catch (SQLException e) {
 472  0
             handleException(e);
 473  0
             return null;
 474  
         }
 475  
     }
 476  
 
 477  
     public PreparedStatement prepareStatement(String sql, int resultSetType,
 478  
                                               int resultSetConcurrency,
 479  
                                               int resultSetHoldability) throws SQLException {
 480  30
         checkOpen();
 481  
         try {
 482  30
             return new DelegatingPreparedStatement(this, _conn.prepareStatement(
 483  
                 sql, resultSetType, resultSetConcurrency, resultSetHoldability));
 484  
         }
 485  0
         catch (SQLException e) {
 486  0
             handleException(e);
 487  0
             return null;
 488  
         }
 489  
     }
 490  
 
 491  
     public CallableStatement prepareCall(String sql, int resultSetType,
 492  
                                          int resultSetConcurrency,
 493  
                                          int resultSetHoldability) throws SQLException {
 494  30
         checkOpen();
 495  
         try {
 496  30
             return new DelegatingCallableStatement(this, _conn.prepareCall(
 497  
                 sql, resultSetType, resultSetConcurrency, resultSetHoldability));
 498  
         }
 499  0
         catch (SQLException e) {
 500  0
             handleException(e);
 501  0
             return null;
 502  
         }
 503  
     }
 504  
 
 505  
     public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
 506  30
         checkOpen();
 507  
         try {
 508  30
             return new DelegatingPreparedStatement(this, _conn.prepareStatement(
 509  
                 sql, autoGeneratedKeys));
 510  
         }
 511  0
         catch (SQLException e) {
 512  0
             handleException(e);
 513  0
             return null;
 514  
         }
 515  
     }
 516  
 
 517  
     public PreparedStatement prepareStatement(String sql, int columnIndexes[]) throws SQLException {
 518  30
         checkOpen();
 519  
         try {
 520  30
             return new DelegatingPreparedStatement(this, _conn.prepareStatement(
 521  
                 sql, columnIndexes));
 522  
         }
 523  0
         catch (SQLException e) {
 524  0
             handleException(e);
 525  0
             return null;
 526  
         }
 527  
     }
 528  
 
 529  
     public PreparedStatement prepareStatement(String sql, String columnNames[]) throws SQLException {
 530  30
         checkOpen();
 531  
         try {
 532  30
             return new DelegatingPreparedStatement(this, _conn.prepareStatement(
 533  
                 sql, columnNames));
 534  
         }
 535  0
         catch (SQLException e) {
 536  0
             handleException(e);
 537  0
             return null;
 538  
         }
 539  
     }
 540  
 
 541  
 /* JDBC_4_ANT_KEY_BEGIN */
 542  
 
 543  
     public boolean isWrapperFor(Class<?> iface) throws SQLException {
 544  0
         return iface.isAssignableFrom(getClass()) || _conn.isWrapperFor(iface);
 545  
     }
 546  
 
 547  
     public <T> T unwrap(Class<T> iface) throws SQLException {
 548  0
         if (iface.isAssignableFrom(getClass())) {
 549  0
             return iface.cast(this);
 550  0
         } else if (iface.isAssignableFrom(_conn.getClass())) {
 551  0
             return iface.cast(_conn);
 552  
         } else {
 553  0
             return _conn.unwrap(iface);
 554  
         }
 555  
     }
 556  
 
 557  
     public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
 558  0
         checkOpen();
 559  
         try {
 560  0
             return _conn.createArrayOf(typeName, elements);
 561  
         }
 562  0
         catch (SQLException e) {
 563  0
             handleException(e);
 564  0
             return null;
 565  
         }
 566  
     }
 567  
 
 568  
     public Blob createBlob() throws SQLException {
 569  0
         checkOpen();
 570  
         try {
 571  0
             return _conn.createBlob();
 572  
         }
 573  0
         catch (SQLException e) {
 574  0
             handleException(e);
 575  0
             return null;
 576  
         }
 577  
     }
 578  
 
 579  
     public Clob createClob() throws SQLException {
 580  0
         checkOpen();
 581  
         try {
 582  0
             return _conn.createClob();
 583  
         }
 584  0
         catch (SQLException e) {
 585  0
             handleException(e);
 586  0
             return null;
 587  
         }
 588  
     }
 589  
 
 590  
     public NClob createNClob() throws SQLException {
 591  0
         checkOpen();
 592  
         try {
 593  0
             return _conn.createNClob();
 594  
         }
 595  0
         catch (SQLException e) {
 596  0
             handleException(e);
 597  0
             return null;
 598  
         }
 599  
     }
 600  
 
 601  
     public SQLXML createSQLXML() throws SQLException {
 602  0
         checkOpen();
 603  
         try {
 604  0
             return _conn.createSQLXML();
 605  
         }
 606  0
         catch (SQLException e) {
 607  0
             handleException(e);
 608  0
             return null;
 609  
         }
 610  
     }
 611  
 
 612  
     public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
 613  0
         checkOpen();
 614  
         try {
 615  0
             return _conn.createStruct(typeName, attributes);
 616  
         }
 617  0
         catch (SQLException e) {
 618  0
             handleException(e);
 619  0
             return null;
 620  
         }
 621  
     }
 622  
 
 623  
     public boolean isValid(int timeout) throws SQLException {
 624  0
         checkOpen();
 625  
         try {
 626  0
             return _conn.isValid(timeout);
 627  
         }
 628  0
         catch (SQLException e) {
 629  0
             handleException(e);
 630  0
             return false;
 631  
         }
 632  
     }
 633  
 
 634  
     public void setClientInfo(String name, String value) throws SQLClientInfoException {
 635  
         try {
 636  0
             checkOpen();
 637  0
             _conn.setClientInfo(name, value);
 638  
         }
 639  0
         catch (SQLClientInfoException e) {
 640  0
             throw e;
 641  
         }
 642  0
         catch (SQLException e) {
 643  0
             throw new SQLClientInfoException("Connection is closed.", EMPTY_FAILED_PROPERTIES, e);
 644  0
         }
 645  0
     }
 646  
 
 647  
     public void setClientInfo(Properties properties) throws SQLClientInfoException {
 648  
         try {
 649  0
             checkOpen();
 650  0
             _conn.setClientInfo(properties);
 651  
         }
 652  0
         catch (SQLClientInfoException e) {
 653  0
             throw e;
 654  
         }
 655  0
         catch (SQLException e) {
 656  0
             throw new SQLClientInfoException("Connection is closed.", EMPTY_FAILED_PROPERTIES, e);
 657  0
         }
 658  0
     }
 659  
 
 660  
     public Properties getClientInfo() throws SQLException {
 661  0
         checkOpen();
 662  
         try {
 663  0
             return _conn.getClientInfo();
 664  
         }
 665  0
         catch (SQLException e) {
 666  0
             handleException(e);
 667  0
             return null;
 668  
         }
 669  
     }
 670  
 
 671  
     public String getClientInfo(String name) throws SQLException {
 672  0
         checkOpen();
 673  
         try {
 674  0
             return _conn.getClientInfo(name);
 675  
         }
 676  0
         catch (SQLException e) {
 677  0
             handleException(e);
 678  0
             return null;
 679  
         }
 680  
     }
 681  
 /* JDBC_4_ANT_KEY_END */
 682  
 }