001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.dbutils;
018    
019    import java.io.PrintWriter;
020    import java.sql.Connection;
021    import java.sql.ResultSet;
022    import java.sql.SQLException;
023    import java.sql.Statement;
024    
025    /**
026     * A collection of JDBC helper methods.  This class is thread safe.
027     */
028    public final class DbUtils {
029    
030        /**
031         * Close a <code>Connection</code>, avoid closing if null.
032         *
033         * @param conn Connection to close.
034         * @throws SQLException if a database access error occurs
035         */
036        public static void close(Connection conn) throws SQLException {
037            if (conn != null) {
038                conn.close();
039            }
040        }
041    
042        /**
043         * Close a <code>ResultSet</code>, avoid closing if null.
044         *
045         * @param rs ResultSet to close.
046         * @throws SQLException if a database access error occurs
047         */
048        public static void close(ResultSet rs) throws SQLException {
049            if (rs != null) {
050                rs.close();
051            }
052        }
053    
054        /**
055         * Close a <code>Statement</code>, avoid closing if null.
056         *
057         * @param stmt Statement to close.
058         * @throws SQLException if a database access error occurs
059         */
060        public static void close(Statement stmt) throws SQLException {
061            if (stmt != null) {
062                stmt.close();
063            }
064        }
065    
066        /**
067         * Close a <code>Connection</code>, avoid closing if null and hide
068         * any SQLExceptions that occur.
069         *
070         * @param conn Connection to close.
071         */
072        public static void closeQuietly(Connection conn) {
073            try {
074                close(conn);
075            } catch (SQLException e) {
076                // quiet
077            }
078        }
079    
080        /**
081         * Close a <code>Connection</code>, <code>Statement</code> and 
082         * <code>ResultSet</code>.  Avoid closing if null and hide any 
083         * SQLExceptions that occur.
084         *
085         * @param conn Connection to close.
086         * @param stmt Statement to close.
087         * @param rs ResultSet to close.
088         */
089        public static void closeQuietly(Connection conn, Statement stmt,
090                ResultSet rs) {
091    
092            try {
093                closeQuietly(rs);
094            } finally {
095                try {
096                    closeQuietly(stmt);
097                } finally {
098                    closeQuietly(conn);
099                }
100            }
101    
102        }
103    
104        /**
105         * Close a <code>ResultSet</code>, avoid closing if null and hide any
106         * SQLExceptions that occur.
107         *
108         * @param rs ResultSet to close.
109         */
110        public static void closeQuietly(ResultSet rs) {
111            try {
112                close(rs);
113            } catch (SQLException e) {
114                // quiet
115            }
116        }
117    
118        /**
119         * Close a <code>Statement</code>, avoid closing if null and hide
120         * any SQLExceptions that occur.
121         *
122         * @param stmt Statement to close.
123         */
124        public static void closeQuietly(Statement stmt) {
125            try {
126                close(stmt);
127            } catch (SQLException e) {
128                // quiet
129            }
130        }
131    
132        /**
133         * Commits a <code>Connection</code> then closes it, avoid closing if null.
134         *
135         * @param conn Connection to close.
136         * @throws SQLException if a database access error occurs
137         */
138        public static void commitAndClose(Connection conn) throws SQLException {
139            if (conn != null) {
140                try {
141                    conn.commit();
142                } finally {
143                    conn.close();
144                }
145            }
146        }
147    
148        /**
149         * Commits a <code>Connection</code> then closes it, avoid closing if null 
150         * and hide any SQLExceptions that occur.
151         *
152         * @param conn Connection to close.
153         */
154        public static void commitAndCloseQuietly(Connection conn) {
155            try {
156                commitAndClose(conn);
157            } catch (SQLException e) {
158                // quiet
159            }
160        }
161    
162        /**
163         * Loads and registers a database driver class.
164         * If this succeeds, it returns true, else it returns false.
165         *
166         * @param driverClassName of driver to load
167         * @return boolean <code>true</code> if the driver was found, otherwise <code>false</code>
168         */
169        public static boolean loadDriver(String driverClassName) {
170            try {
171                Class.forName(driverClassName).newInstance();
172                return true;
173    
174            } catch (ClassNotFoundException e) {
175                return false;
176    
177            } catch (IllegalAccessException e) {
178                // Constructor is private, OK for DriverManager contract
179                return true;
180    
181            } catch (InstantiationException e) {
182                return false;
183    
184            } catch (Throwable e) {
185                return false;
186            }
187        }
188    
189        /**
190         * Print the stack trace for a SQLException to STDERR.
191         *
192         * @param e SQLException to print stack trace of
193         */
194        public static void printStackTrace(SQLException e) {
195            printStackTrace(e, new PrintWriter(System.err));
196        }
197    
198        /**
199         * Print the stack trace for a SQLException to a 
200         * specified PrintWriter. 
201         *
202         * @param e SQLException to print stack trace of
203         * @param pw PrintWriter to print to
204         */
205        public static void printStackTrace(SQLException e, PrintWriter pw) {
206    
207            SQLException next = e;
208            while (next != null) {
209                next.printStackTrace(pw);
210                next = next.getNextException();
211                if (next != null) {
212                    pw.println("Next SQLException:");
213                }
214            }
215        }
216    
217        /**
218         * Print warnings on a Connection to STDERR.
219         *
220         * @param conn Connection to print warnings from
221         */
222        public static void printWarnings(Connection conn) {
223            printWarnings(conn, new PrintWriter(System.err));
224        }
225    
226        /**
227         * Print warnings on a Connection to a specified PrintWriter. 
228         *
229         * @param conn Connection to print warnings from
230         * @param pw PrintWriter to print to
231         */
232        public static void printWarnings(Connection conn, PrintWriter pw) {
233            if (conn != null) {
234                try {
235                    printStackTrace(conn.getWarnings(), pw);
236                } catch (SQLException e) {
237                    printStackTrace(e, pw);
238                }
239            }
240        }
241    
242        /**
243         * Rollback any changes made on the given connection.
244         * @param conn Connection to rollback.  A null value is legal.
245         * @throws SQLException if a database access error occurs
246         */
247        public static void rollback(Connection conn) throws SQLException {
248            if (conn != null) {
249                conn.rollback();
250            }
251        }
252        
253        /**
254         * Performs a rollback on the <code>Connection</code> then closes it, 
255         * avoid closing if null.
256         *
257         * @param conn Connection to rollback.  A null value is legal.
258         * @throws SQLException if a database access error occurs
259         * @since DbUtils 1.1
260         */
261        public static void rollbackAndClose(Connection conn) throws SQLException {
262            if (conn != null) {
263                try {
264                    conn.rollback();
265                } finally {
266                    conn.close();
267                }
268            }
269        }
270    
271        /**
272         * Performs a rollback on the <code>Connection</code> then closes it, 
273         * avoid closing if null and hide any SQLExceptions that occur.
274         *
275         * @param conn Connection to rollback.  A null value is legal.
276         * @since DbUtils 1.1
277         */
278        public static void rollbackAndCloseQuietly(Connection conn) {
279            try {
280                rollbackAndClose(conn);
281            } catch (SQLException e) {
282                // quiet
283            }
284        }
285    
286    }