Home » commons-dbcp-1.2.2-src » org.apache.commons » dbcp » [javadoc | source]
    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.List;
   28   import java.util.Map;
   29   
   30   /**
   31    * A base delegating implementation of {@link Connection}.
   32    * <p>
   33    * All of the methods from the {@link Connection} interface
   34    * simply check to see that the {@link Connection} is active,
   35    * and call the corresponding method on the "delegate"
   36    * provided in my constructor.
   37    * <p>
   38    * Extends AbandonedTrace to implement Connection tracking and
   39    * logging of code which created the Connection. Tracking the
   40    * Connection ensures that the AbandonedObjectPool can close
   41    * this connection and recycle it if its pool of connections
   42    * is nearing exhaustion and this connection's last usage is
   43    * older than the removeAbandonedTimeout.
   44    *
   45    * @author Rodney Waldhoff
   46    * @author Glenn L. Nielsen
   47    * @author James House
   48    * @author Dirk Verbeeck
   49    * @version $Revision: 500687 $ $Date: 2007-01-27 16:33:47 -0700 (Sat, 27 Jan 2007) $
   50    */
   51   public class DelegatingConnection extends AbandonedTrace
   52           implements Connection {
   53       /** My delegate {@link Connection}. */
   54       protected Connection _conn = null;
   55   
   56       protected boolean _closed = false;
   57       
   58       /**
   59        * Create a wrapper for the Connectin which traces this
   60        * Connection in the AbandonedObjectPool.
   61        *
   62        * @param c the {@link Connection} to delegate all calls to.
   63        */
   64       public DelegatingConnection(Connection c) {
   65           super();
   66           _conn = c;
   67       }
   68   
   69       /**
   70        * Create a wrapper for the Connection which traces
   71        * the Statements created so that any unclosed Statements
   72        * can be closed when this Connection is closed.
   73        *
   74        * @param c the {@link Connection} to delegate all calls to.
   75        * @param config the configuration for tracing abandoned objects
   76        * @deprecated AbandonedConfig is now deprecated.
   77        */
   78       public DelegatingConnection(Connection c, AbandonedConfig config) {
   79           super(config);
   80           _conn = c;
   81       }
   82   
   83       /**
   84        * Returns a string representation of the metadata associated with
   85        * the innnermost delegate connection.
   86        * 
   87        * @since 1.2.2
   88        */
   89       public String toString() {
   90           String s = null;
   91           
   92           Connection c = this.getInnermostDelegate();
   93           if (c != null) {
   94               try {
   95                   if (c.isClosed()) {
   96                       s = "connection is closed";
   97                   }
   98                   else {
   99                       DatabaseMetaData meta = c.getMetaData();
  100                       if (meta != null) {
  101                           StringBuffer sb = new StringBuffer();
  102                           sb.append(meta.getURL());
  103                           sb.append(", UserName=");
  104                           sb.append(meta.getUserName());
  105                           sb.append(", ");
  106                           sb.append(meta.getDriverName());
  107                           s = sb.toString();
  108                       }
  109                   }
  110               }
  111               catch (SQLException ex) {
  112                   s = null;
  113               }
  114           }
  115           
  116           if (s == null) {
  117               s = super.toString();
  118           }
  119           
  120           return s;
  121       }
  122   
  123       /**
  124        * Returns my underlying {@link Connection}.
  125        * @return my underlying {@link Connection}.
  126        */
  127       public Connection getDelegate() {
  128           return _conn;
  129       }
  130       
  131       /**
  132        * Compares innermost delegate to the given connection.
  133        * 
  134        * @param c connection to compare innermost delegate with
  135        * @return true if innermost delegate equals <code>c</code>
  136        * @since 1.2.2
  137        */
  138       public boolean innermostDelegateEquals(Connection c) {
  139           Connection innerCon = getInnermostDelegate();
  140           if (innerCon == null) {
  141               return c == null;
  142           } else {
  143               return innerCon.equals(c);
  144           }
  145       }
  146   
  147       public boolean equals(Object obj) {
  148           if (obj == null) {
  149               return false;
  150           }
  151           if (obj == this) {
  152               return true;
  153           }
  154           Connection delegate = getInnermostDelegate();
  155           if (delegate == null) {
  156               return false;
  157           }
  158           if (obj instanceof DelegatingConnection) {    
  159               DelegatingConnection c = (DelegatingConnection) obj;
  160               return c.innermostDelegateEquals(delegate);
  161           }
  162           else {
  163               return delegate.equals(obj);
  164           }
  165       }
  166   
  167       public int hashCode() {
  168           Object obj = getInnermostDelegate();
  169           if (obj == null) {
  170               return 0;
  171           }
  172           return obj.hashCode();
  173       }
  174   
  175   
  176       /**
  177        * If my underlying {@link Connection} is not a
  178        * <tt>DelegatingConnection</tt>, returns it,
  179        * otherwise recursively invokes this method on
  180        * my delegate.
  181        * <p>
  182        * Hence this method will return the first
  183        * delegate that is not a <tt>DelegatingConnection</tt>,
  184        * or <tt>null</tt> when no non-<tt>DelegatingConnection</tt>
  185        * delegate can be found by transversing this chain.
  186        * <p>
  187        * This method is useful when you may have nested
  188        * <tt>DelegatingConnection</tt>s, and you want to make
  189        * sure to obtain a "genuine" {@link Connection}.
  190        */
  191       public Connection getInnermostDelegate() {
  192           Connection c = _conn;
  193           while(c != null && c instanceof DelegatingConnection) {
  194               c = ((DelegatingConnection)c).getDelegate();
  195               if(this == c) {
  196                   return null;
  197               }
  198           }
  199           return c;
  200       }
  201   
  202       /** Sets my delegate. */
  203       public void setDelegate(Connection c) {
  204           _conn = c;
  205       }
  206   
  207       /**
  208        * Closes the underlying connection, and close
  209        * any Statements that were not explicitly closed.
  210        */
  211       public void close() throws SQLException
  212       {
  213           passivate();
  214           _conn.close();
  215       }
  216   
  217       protected void handleException(SQLException e) throws SQLException {
  218           throw e;
  219       }
  220   
  221       public Statement createStatement() throws SQLException {
  222           checkOpen();
  223           try {
  224               return new DelegatingStatement(this, _conn.createStatement());
  225           }
  226           catch (SQLException e) {
  227               handleException(e);
  228               return null;
  229           }
  230       }
  231   
  232       public Statement createStatement(int resultSetType,
  233                                        int resultSetConcurrency) throws SQLException {
  234           checkOpen();
  235           try {
  236               return new DelegatingStatement
  237                   (this, _conn.createStatement(resultSetType,resultSetConcurrency));
  238           }
  239           catch (SQLException e) {
  240               handleException(e);
  241               return null;
  242           }
  243       }
  244   
  245       public PreparedStatement prepareStatement(String sql) throws SQLException {
  246           checkOpen();
  247           try {
  248               return new DelegatingPreparedStatement
  249                   (this, _conn.prepareStatement(sql));
  250           }
  251           catch (SQLException e) {
  252               handleException(e);
  253               return null;
  254           }
  255       }
  256   
  257       public PreparedStatement prepareStatement(String sql,
  258                                                 int resultSetType,
  259                                                 int resultSetConcurrency) throws SQLException {
  260           checkOpen();
  261           try {
  262               return new DelegatingPreparedStatement
  263                   (this, _conn.prepareStatement
  264                       (sql,resultSetType,resultSetConcurrency));
  265           }
  266           catch (SQLException e) {
  267               handleException(e);
  268               return null;
  269           }
  270       }
  271   
  272       public CallableStatement prepareCall(String sql) throws SQLException {
  273           checkOpen();
  274           try {
  275               return new DelegatingCallableStatement(this, _conn.prepareCall(sql));
  276           }
  277           catch (SQLException e) {
  278               handleException(e);
  279               return null;
  280           }
  281       }
  282   
  283       public CallableStatement prepareCall(String sql,
  284                                            int resultSetType,
  285                                            int resultSetConcurrency) throws SQLException {
  286           checkOpen();
  287           try {
  288               return new DelegatingCallableStatement
  289                   (this, _conn.prepareCall(sql, resultSetType,resultSetConcurrency));
  290           }
  291           catch (SQLException e) {
  292               handleException(e);
  293               return null;
  294           }
  295       }
  296   
  297       public void clearWarnings() throws SQLException
  298       { checkOpen(); try { _conn.clearWarnings(); } catch (SQLException e) { handleException(e); } }
  299       
  300       public void commit() throws SQLException
  301       { checkOpen(); try { _conn.commit(); } catch (SQLException e) { handleException(e); } }
  302       
  303       public boolean getAutoCommit() throws SQLException
  304       { checkOpen(); try { return _conn.getAutoCommit(); } catch (SQLException e) { handleException(e); return false; } 
  305       }
  306       public String getCatalog() throws SQLException
  307       { checkOpen(); try { return _conn.getCatalog(); } catch (SQLException e) { handleException(e); return null; } }
  308       
  309       public DatabaseMetaData getMetaData() throws SQLException
  310       { checkOpen(); try { return _conn.getMetaData(); } catch (SQLException e) { handleException(e); return null; } }
  311       
  312       public int getTransactionIsolation() throws SQLException
  313       { checkOpen(); try { return _conn.getTransactionIsolation(); } catch (SQLException e) { handleException(e); return -1; } }
  314       
  315       public Map getTypeMap() throws SQLException
  316       { checkOpen(); try { return _conn.getTypeMap(); } catch (SQLException e) { handleException(e); return null; } }
  317       
  318       public SQLWarning getWarnings() throws SQLException
  319       { checkOpen(); try { return _conn.getWarnings(); } catch (SQLException e) { handleException(e); return null; } }
  320       
  321       public boolean isReadOnly() throws SQLException
  322       { checkOpen(); try { return _conn.isReadOnly(); } catch (SQLException e) { handleException(e); return false; } }
  323       
  324       public String nativeSQL(String sql) throws SQLException
  325       { checkOpen(); try { return _conn.nativeSQL(sql); } catch (SQLException e) { handleException(e); return null; } }
  326       
  327       public void rollback() throws SQLException
  328       { checkOpen(); try {  _conn.rollback(); } catch (SQLException e) { handleException(e); } }
  329       
  330       public void setAutoCommit(boolean autoCommit) throws SQLException
  331       { checkOpen(); try { _conn.setAutoCommit(autoCommit); } catch (SQLException e) { handleException(e); } }
  332   
  333       public void setCatalog(String catalog) throws SQLException
  334       { checkOpen(); try { _conn.setCatalog(catalog); } catch (SQLException e) { handleException(e); } }
  335   
  336       public void setReadOnly(boolean readOnly) throws SQLException
  337       { checkOpen(); try { _conn.setReadOnly(readOnly); } catch (SQLException e) { handleException(e); } }
  338   
  339       public void setTransactionIsolation(int level) throws SQLException
  340       { checkOpen(); try { _conn.setTransactionIsolation(level); } catch (SQLException e) { handleException(e); } }
  341   
  342       public void setTypeMap(Map map) throws SQLException
  343       { checkOpen(); try { _conn.setTypeMap(map); } catch (SQLException e) { handleException(e); } }
  344   
  345       public boolean isClosed() throws SQLException {
  346            if(_closed || _conn.isClosed()) {
  347                return true;
  348            }
  349            return false;
  350       }
  351   
  352       protected void checkOpen() throws SQLException {
  353           if(_closed) {
  354               throw new SQLException
  355                   ("Connection " + _conn + " is closed.");
  356           }
  357       }
  358   
  359       protected void activate() {
  360           _closed = false;
  361           setLastUsed();
  362           if(_conn instanceof DelegatingConnection) {
  363               ((DelegatingConnection)_conn).activate();
  364           }
  365       }
  366   
  367       protected void passivate() throws SQLException {
  368           try {
  369               // The JDBC spec requires that a Connection close any open
  370               // Statement's when it is closed.
  371               List statements = getTrace();
  372               if( statements != null) {
  373                   Statement[] set = new Statement[statements.size()];
  374                   statements.toArray(set);
  375                   for (int i = 0; i < set.length; i++) {
  376                       set[i].close();
  377                   }
  378                   clearTrace();
  379               }
  380               setLastUsed(0);
  381               if(_conn instanceof DelegatingConnection) {
  382                   ((DelegatingConnection)_conn).passivate();
  383               }
  384           }
  385           finally {
  386               _closed = true;
  387           }
  388       }
  389   
  390       // ------------------- JDBC 3.0 -----------------------------------------
  391       // Will be commented by the build process on a JDBC 2.0 system
  392   
  393   /* JDBC_3_ANT_KEY_BEGIN */
  394   
  395       public int getHoldability() throws SQLException
  396       { checkOpen(); try { return _conn.getHoldability(); } catch (SQLException e) { handleException(e); return 0; } }
  397   
  398       public void setHoldability(int holdability) throws SQLException
  399       { checkOpen(); try { _conn.setHoldability(holdability); } catch (SQLException e) { handleException(e); } }
  400   
  401       public java.sql.Savepoint setSavepoint() throws SQLException
  402       { checkOpen(); try { return _conn.setSavepoint(); } catch (SQLException e) { handleException(e); return null; } }
  403   
  404       public java.sql.Savepoint setSavepoint(String name) throws SQLException
  405       { checkOpen(); try { return _conn.setSavepoint(name); } catch (SQLException e) { handleException(e); return null; } }
  406   
  407       public void rollback(java.sql.Savepoint savepoint) throws SQLException
  408       { checkOpen(); try { _conn.rollback(savepoint); } catch (SQLException e) { handleException(e); } }
  409   
  410       public void releaseSavepoint(java.sql.Savepoint savepoint) throws SQLException
  411       { checkOpen(); try { _conn.releaseSavepoint(savepoint); } catch (SQLException e) { handleException(e); } }
  412   
  413       public Statement createStatement(int resultSetType,
  414                                        int resultSetConcurrency,
  415                                        int resultSetHoldability) throws SQLException {
  416           checkOpen();
  417           try {
  418               return new DelegatingStatement(this, _conn.createStatement(
  419                   resultSetType, resultSetConcurrency, resultSetHoldability));
  420           }
  421           catch (SQLException e) {
  422               handleException(e);
  423               return null;
  424           }
  425       }
  426   
  427       public PreparedStatement prepareStatement(String sql, int resultSetType,
  428                                                 int resultSetConcurrency,
  429                                                 int resultSetHoldability) throws SQLException {
  430           checkOpen();
  431           try {
  432               return new DelegatingPreparedStatement(this, _conn.prepareStatement(
  433                   sql, resultSetType, resultSetConcurrency, resultSetHoldability));
  434           }
  435           catch (SQLException e) {
  436               handleException(e);
  437               return null;
  438           }
  439       }
  440   
  441       public CallableStatement prepareCall(String sql, int resultSetType,
  442                                            int resultSetConcurrency,
  443                                            int resultSetHoldability) throws SQLException {
  444           checkOpen();
  445           try {
  446               return new DelegatingCallableStatement(this, _conn.prepareCall(
  447                   sql, resultSetType, resultSetConcurrency, resultSetHoldability));
  448           }
  449           catch (SQLException e) {
  450               handleException(e);
  451               return null;
  452           }
  453       }
  454   
  455       public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
  456           checkOpen();
  457           try {
  458               return new DelegatingPreparedStatement(this, _conn.prepareStatement(
  459                   sql, autoGeneratedKeys));
  460           }
  461           catch (SQLException e) {
  462               handleException(e);
  463               return null;
  464           }
  465       }
  466   
  467       public PreparedStatement prepareStatement(String sql, int columnIndexes[]) throws SQLException {
  468           checkOpen();
  469           try {
  470               return new DelegatingPreparedStatement(this, _conn.prepareStatement(
  471                   sql, columnIndexes));
  472           }
  473           catch (SQLException e) {
  474               handleException(e);
  475               return null;
  476           }
  477       }
  478   
  479       public PreparedStatement prepareStatement(String sql, String columnNames[]) throws SQLException {
  480           checkOpen();
  481           try {
  482               return new DelegatingPreparedStatement(this, _conn.prepareStatement(
  483                   sql, columnNames));
  484           }
  485           catch (SQLException e) {
  486               handleException(e);
  487               return null;
  488           }
  489       }
  490   /* JDBC_3_ANT_KEY_END */
  491   }

Save This Page
Home » commons-dbcp-1.2.2-src » org.apache.commons » dbcp » [javadoc | source]