1 /************************************************************************
2 * Copyright (c) 2000-2006 The Apache Software Foundation. *
3 * All rights reserved. *
4 * ------------------------------------------------------------------- *
5 * Licensed under the Apache License, Version 2.0 (the "License"); you *
6 * may not use this file except in compliance with the License. You *
7 * 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 *
14 * implied. See the License for the specific language governing *
15 * permissions and limitations under the License. *
16 ***********************************************************************/
17
18 package org.apache.james.util;
19
20 import java.sql.Connection;
21 import java.sql.DatabaseMetaData;
22 import java.sql.ResultSet;
23 import java.sql.SQLException;
24 import java.sql.Statement;
25 import java.util.Locale;
26
27 /***
28 * <p>Helper class for managing common JDBC tasks.</p>
29 *
30 * <p>This class is abstract to allow implementations to
31 * take advantage of different logging capabilities/interfaces in
32 * different parts of the code.</p>
33 *
34 * @version CVS $Revision: 365582 $ $Date: 2006-01-03 08:51:21 +0000 (mar, 03 gen 2006) $
35 */
36 abstract public class JDBCUtil
37 {
38 /***
39 * An abstract method which child classes override to handle logging of
40 * errors in their particular environments.
41 *
42 * @param errorString the error message generated
43 */
44 abstract protected void delegatedLog(String errorString);
45
46 /***
47 * Checks database metadata to see if a table exists.
48 * Try UPPER, lower, and MixedCase, to see if the table is there.
49 *
50 * @param dbMetaData the database metadata to be used to look up this table
51 * @param tableName the table name
52 *
53 * @throws SQLException if an exception is encountered while accessing the database
54 */
55 public boolean tableExists(DatabaseMetaData dbMetaData, String tableName)
56 throws SQLException {
57 return ( tableExistsCaseSensitive(dbMetaData, tableName) ||
58 tableExistsCaseSensitive(dbMetaData, tableName.toUpperCase(Locale.US)) ||
59 tableExistsCaseSensitive(dbMetaData, tableName.toLowerCase(Locale.US)) );
60 }
61
62 /***
63 * Checks database metadata to see if a table exists. This method
64 * is sensitive to the case of the provided table name.
65 *
66 * @param dbMetaData the database metadata to be used to look up this table
67 * @param tableName the case sensitive table name
68 *
69 * @throws SQLException if an exception is encountered while accessing the database
70 */
71 public boolean tableExistsCaseSensitive(DatabaseMetaData dbMetaData, String tableName)
72 throws SQLException {
73 ResultSet rsTables = dbMetaData.getTables(null, null, tableName, null);
74 try {
75 boolean found = rsTables.next();
76 return found;
77 } finally {
78 closeJDBCResultSet(rsTables);
79 }
80 }
81
82 /***
83 * Checks database metadata to see if a column exists in a table
84 * Try UPPER, lower, and MixedCase, both on the table name and the column name, to see if the column is there.
85 *
86 * @param dbMetaData the database metadata to be used to look up this column
87 * @param tableName the table name
88 * @param columnName the column name
89 *
90 * @throws SQLException if an exception is encountered while accessing the database
91 */
92 public boolean columnExists(DatabaseMetaData dbMetaData, String tableName, String columnName)
93 throws SQLException {
94 return ( columnExistsCaseSensitive(dbMetaData, tableName, columnName) ||
95 columnExistsCaseSensitive(dbMetaData, tableName, columnName.toUpperCase(Locale.US)) ||
96 columnExistsCaseSensitive(dbMetaData, tableName, columnName.toLowerCase(Locale.US)) ||
97 columnExistsCaseSensitive(dbMetaData, tableName.toUpperCase(Locale.US), columnName) ||
98 columnExistsCaseSensitive(dbMetaData, tableName.toUpperCase(Locale.US), columnName.toUpperCase(Locale.US)) ||
99 columnExistsCaseSensitive(dbMetaData, tableName.toUpperCase(Locale.US), columnName.toLowerCase(Locale.US)) ||
100 columnExistsCaseSensitive(dbMetaData, tableName.toLowerCase(Locale.US), columnName) ||
101 columnExistsCaseSensitive(dbMetaData, tableName.toLowerCase(Locale.US), columnName.toUpperCase(Locale.US)) ||
102 columnExistsCaseSensitive(dbMetaData, tableName.toLowerCase(Locale.US), columnName.toLowerCase(Locale.US)) );
103 }
104
105 /***
106 * Checks database metadata to see if a column exists in a table. This method
107 * is sensitive to the case of both the provided table name and column name.
108 *
109 * @param dbMetaData the database metadata to be used to look up this column
110 * @param tableName the case sensitive table name
111 * @param columnName the case sensitive column name
112 *
113 * @throws SQLException if an exception is encountered while accessing the database
114 */
115 public boolean columnExistsCaseSensitive(DatabaseMetaData dbMetaData, String tableName, String columnName)
116 throws SQLException {
117 ResultSet rsTables = dbMetaData.getColumns(null, null, tableName, columnName);
118 try {
119 boolean found = rsTables.next();
120 return found;
121 } finally {
122 closeJDBCResultSet(rsTables);
123 }
124 }
125
126 /***
127 * Closes database connection and logs if an error
128 * is encountered
129 *
130 * @param conn the connection to be closed
131 */
132 public void closeJDBCConnection(Connection conn) {
133 try {
134 if (conn != null) {
135 conn.close();
136 }
137 } catch (SQLException sqle) {
138
139 subclassLogWrapper("Unexpected exception while closing database connection.");
140 }
141 }
142
143 /***
144 * Closes database statement and logs if an error
145 * is encountered
146 *
147 * @param stmt the statement to be closed
148 */
149 public void closeJDBCStatement(Statement stmt) {
150 try {
151 if (stmt != null) {
152 stmt.close();
153 }
154 } catch (SQLException sqle) {
155
156 subclassLogWrapper("Unexpected exception while closing database statement.");
157 }
158 }
159
160 /***
161 * Closes database result set and logs if an error
162 * is encountered
163 *
164 * @param aResultSet the result set to be closed
165 */
166 public void closeJDBCResultSet(ResultSet aResultSet ) {
167 try {
168 if (aResultSet != null) {
169 aResultSet.close();
170 }
171 } catch (SQLException sqle) {
172
173 subclassLogWrapper("Unexpected exception while closing database result set.");
174 }
175 }
176
177 /***
178 * Wraps the delegated call to the subclass logging method with a Throwable
179 * wrapper. All throwables generated by the subclass logging method are
180 * caught and ignored.
181 *
182 * @param logString the raw string to be passed to the logging method implemented
183 * by the subclass
184 */
185 private void subclassLogWrapper(String logString)
186 {
187 try {
188 delegatedLog(logString);
189 }
190 catch(Throwable t) {
191
192 }
193 }
194
195 }