001    package org.rakeshv.dbutils;
002    
003    import java.sql.Connection;
004    import java.sql.ResultSet;
005    import java.sql.SQLException;
006    import java.sql.Statement;
007    
008    import java.util.logging.Level;
009    import java.util.logging.Logger;
010    
011    /**
012     * A convenience class to close JDBC resources in an error free manner.
013     * Any errors encountered while closing the resources will be logged
014     * using the {@link #logger}.  You can configure the location and other
015     * properties for the logger through the <code>logging.properties</code>
016     * file.
017     *
018     * @author Rakesh Vidyadharan 25<sup><small>th</small></sup> August 2003
019     * <p>Copyright 2003 Rakesh Vidyadharan</p>
020     *
021     * @version $Id: CloseResources.java,v 1.3 2005/03/03 02:19:08 rakesh Exp $
022     */
023    public class CloseResources extends Object
024    {
025      /**
026       * The logger instance used to log errors or other messages.
027       */
028      private static final Logger logger = 
029        Logger.getLogger( "org.rakeshv.dbutils.CloseResources" );
030    
031      /**
032       * A constant used to indicate that only the specified JDBC resource
033       * should be closed.
034       * 
035       * <p><code>{@value}</code></p>
036       */
037      public static final boolean CLOSE_SPECIFIED_RESOURCE = false;
038    
039      /**
040       * A constant used to indicate that all the JDBC resources associated
041       * with the specified resource should be closed.
042       */
043      public static final boolean CLOSE_ASSOCIATED_RESOURCES = true;
044    
045      /**
046       * Default constructor.  Cannot be instantiated.
047       */
048      private CloseResources() {}
049    
050      /**
051       * Utility method to close the specified <code>ResultSet</code> in
052       * a fail-safe manner.  Any errors encountered while closing the
053       * result set will be logged to {@link #logger} as a warning.
054       *
055       * @param resultSet The result set that is to be closed.
056       */
057      public static void close( ResultSet resultSet )
058      {
059        try
060        {
061          if ( resultSet != null ) resultSet.close();
062        }
063        catch ( SQLException sex )
064        {
065          logger.log( Level.WARNING,
066              "Error closing ResultSet.", sex );
067        }
068      }
069    
070      /**
071       * Utility method to close the specified <code>ResultSet</code> in
072       * a fail-safe manner.  If the <code>closeAssociatedResources</code>
073       * parameter is set to {@link #CLOSE_ASSOCIATED_RESOURCES}, then the 
074       * <code>Statement</code> and <code>Connection</code> associated with 
075       * the specified result set are closed, otherwise, only the specifed
076       * result set will be closed.
077       *
078       * @see #close( ResultSet )
079       * @see #close( Statement )
080       * @see #close( Connection )
081       * @param resultSet The result set that is to be closed.
082       * @param closeAssociatedResources The flag indicating the resources
083       *   that are to be closed.
084       */
085      public static void close( ResultSet resultSet,
086          boolean closeAssociatedResources )
087      {
088        if ( resultSet == null ) return;
089    
090        if ( closeAssociatedResources == CloseResources.CLOSE_ASSOCIATED_RESOURCES )
091        {
092          try
093          {
094            Statement statement = resultSet.getStatement();
095            close( resultSet );
096            close( statement, closeAssociatedResources );
097          }
098          catch ( SQLException sex )
099          {
100            logger.log( Level.WARNING,
101                "Error closing ResultSet or associated resources.", sex );
102          }
103        }
104        else
105        {
106          close( resultSet );
107        }
108      }
109    
110      /**
111       * Utility method to close the specified <code>Statement</code> in
112       * a fail-safe manner.  Any errors encountered while closing the
113       * statement will be logged to {@link #logger} as a warning.
114       *
115       * @param statement The statement that is to be closed.
116       */
117      public static void close( Statement statement )
118      {
119        try
120        {
121          if ( statement != null ) statement.close();
122        }
123        catch ( SQLException sex )
124        {
125          logger.log( Level.WARNING,
126                "Error closing Statement.", sex );
127        }
128      }
129    
130      /**
131       * Utility method to close the specified <code>Statement</code> in
132       * a fail-safe manner.  If the <code>closeAssociatedResources</code>
133       * parameter is set to {@link #CLOSE_ASSOCIATED_RESOURCES}, then the 
134       * <code>Connection</code> associated with the specified statement is
135       * also closed, otherwise, only the specifed statement will be closed.
136       *
137       * @see #close( Statement )
138       * @see #close( Connection )
139       * @param statement The statement that is to be closed.
140       * @param closeAssociatedResources The flag indicating the resources
141       *   that are to be closed.
142       */
143      public static void close( Statement statement,
144          boolean closeAssociatedResources )
145      {
146        if ( statement == null ) return;
147    
148        if ( closeAssociatedResources == CloseResources.CLOSE_ASSOCIATED_RESOURCES )
149        {
150          try
151          {
152            Connection connection = statement.getConnection();
153            close( statement );
154            close( connection );
155          }
156          catch ( SQLException sex )
157          {
158            logger.log( Level.WARNING,
159                "Error closing Statement or associated resources.", sex );
160          }
161        }
162        else
163        {
164          close( statement );
165        }
166      }
167    
168      /**
169       * Utility method to close the specified <code>Connection</code> in
170       * a fail-safe manner.  Any errors encountered while closing the
171       * connection will be logged to {@link #logger} as a warning.
172       *
173       * @param connection The connection that is to be closed.
174       */
175      public static void close( Connection connection )
176      {
177        try
178        {
179          if ( connection != null ) connection.close();
180        }
181        catch ( SQLException sex )
182        {
183          logger.log( Level.WARNING, "Error closing Connection.", sex );
184        }
185      }
186    
187      /**
188       * Utility method to close the specified <code>Connection</code> in
189       * a fail-safe manner.  Set the <code>autoCommit</code> property of
190       * the connection to the specified value.  Any errors encountered 
191       * while closing the connection will be logged to {@link #logger} as 
192       * a warning.
193       *
194       * @see #close( Connection )
195       * @param connection The connection that is to be closed.
196       * @param autoCommit The value to set for the autoCommit property.
197       */
198      public static void close( Connection connection, boolean autoCommit )
199      {
200        try
201        {
202          if ( connection != null ) 
203          {
204            connection.setAutoCommit( autoCommit );
205          }
206        }
207        catch ( SQLException sex )
208        {
209          logger.log( Level.WARNING,
210              "Error setting autoCommit to " + autoCommit + ".", sex );
211        }
212    
213        close( connection );
214      }
215    }