##### Coverage Report - org.apache.commons.configuration.DatabaseConfiguration

Classes in this File | Line Coverage | Branch Coverage | Complexity
DatabaseConfiguration |
98% | 163/167
100% | 24/24
| 3.3846153846153846;3,385

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.configuration;
19 |  |
20 |  |
     import java.sql.Connection;
21 |  |
     import java.sql.PreparedStatement;
22 |  |
     import java.sql.ResultSet;
23 |  |
     import java.sql.SQLException;
24 |  |
     import java.sql.Statement;
25 |  |
     import java.util.ArrayList;
26 |  |
     import java.util.Collection;
27 |  |
     import java.util.Iterator;
28 |  |
     import java.util.List;
29 |  |
30 |  |
     import javax.sql.DataSource;
31 |  |
32 |  |
     import org.apache.commons.collections.CollectionUtils;
33 |  |
     import org.apache.commons.logging.LogFactory;
34 |  |
35 |  |
     /**
36 |  |
      * Configuration stored in a database. The properties are retrieved from a
37 |  |
      * table containing at least one column for the keys, and one column for the
38 |  |
      * values. It's possible to store several configurations in the same table by
39 |  |
      * adding a column containing the name of the configuration. The name of the
40 |  |
      * table and the columns is specified in the constructor.
41 |  |
      *
42 |  |
      * <h4>Example 1 - One configuration per table</h4>
43 |  |
      *
44 |  |
      * <pre>
45 |  |
      * CREATE TABLE myconfig (
46 |  |
      *     `key`   VARCHAR NOT NULL PRIMARY KEY,
47 |  |
      *     `value` VARCHAR
48 |  |
      * );
49 |  |
      *
50 |  |
      * INSERT INTO myconfig (key, value) VALUES ('foo', 'bar');
51 |  |
      *
52 |  |
      *
53 |  |
      * Configuration config = new DatabaseConfiguration(datasource, "myconfig", "key", "value");
54 |  |
      * String value = config.getString("foo");
55 |  |
      * </pre>
56 |  |
      *
57 |  |
      * <h4>Example 2 - Multiple configurations per table</h4>
58 |  |
      *
59 |  |
      * <pre>
60 |  |
      * CREATE TABLE myconfigs (
61 |  |
      *     `name`  VARCHAR NOT NULL,
62 |  |
      *     `key`   VARCHAR NOT NULL,
63 |  |
      *     `value` VARCHAR,
64 |  |
      *     CONSTRAINT sys_pk_myconfigs PRIMARY KEY (`name`, `key`)
65 |  |
      * );
66 |  |
      *
67 |  |
      * INSERT INTO myconfigs (name, key, value) VALUES ('config1', 'key1', 'value1');
68 |  |
      * INSERT INTO myconfigs (name, key, value) VALUES ('config2', 'key2', 'value2');
69 |  |
      *
70 |  |
      *
71 |  |
      * Configuration config1 = new DatabaseConfiguration(datasource, "myconfigs", "name", "key", "value", "config1");
72 |  |
      * String value1 = conf.getString("key1");
73 |  |
      *
74 |  |
      * Configuration config2 = new DatabaseConfiguration(datasource, "myconfigs", "name", "key", "value", "config2");
75 |  |
      * String value2 = conf.getString("key2");
76 |  |
      * </pre>
77 |  |
      *
78 |  |
      * @since 1.0
79 |  |
      *
80 |  |
      * @author <a href="mailto:ebourg@apache.org">Emmanuel Bourg</a>
81 |  |
      * @version $Revision: 589380 $, $Date: 2007-10-28 17:37:35 +0100 (So, 28 Okt 2007) $
82 |  |
      */
83 |  |
     public class DatabaseConfiguration extends AbstractConfiguration
84 |  |
     {
85 |  |
         /** The datasource to connect to the database. */
86 |  |
         private DataSource datasource;
87 |  |
88 |  |
         /** The name of the table containing the configurations. */
89 |  |
         private String table;
90 |  |
91 |  |
         /** The column containing the name of the configuration. */
92 |  |
         private String nameColumn;
93 |  |
94 |  |
         /** The column containing the keys. */
95 |  |
         private String keyColumn;
96 |  |
97 |  |
         /** The column containing the values. */
98 |  |
         private String valueColumn;
99 |  |
100 |  |
         /** The name of the configuration. */
101 |  |
         private String name;
102 |  |
103 |  |
         /**
104 |  |
          * Build a configuration from a table containing multiple configurations.
105 |  |
          *
106 |  |
          * @param datasource    the datasource to connect to the database
107 |  |
          * @param table         the name of the table containing the configurations
108 |  |
          * @param nameColumn    the column containing the name of the configuration
109 |  |
          * @param keyColumn     the column containing the keys of the configuration
110 |  |
          * @param valueColumn   the column containing the values of the configuration
111 |  |
          * @param name          the name of the configuration
112 |  |
          */
113 |  |
         public DatabaseConfiguration(DataSource datasource, String table, String nameColumn,
114 |  |
                 String keyColumn, String valueColumn, String name)
115 | 30 |
         {
116 | 30 |
             this.datasource = datasource;
117 | 30 |
             this.table = table;
118 | 30 |
             this.nameColumn = nameColumn;
119 | 30 |
             this.keyColumn = keyColumn;
120 | 30 |
             this.valueColumn = valueColumn;
121 | 30 |
             this.name = name;
122 | 30 |
             setLogger(LogFactory.getLog(getClass()));
123 | 30 |
             addErrorLogListener();  // log errors per default
124 | 30 |
         }
125 |  |
126 |  |
         /**
127 |  |
          * Build a configuration from a table.-
128 |  |
          *
129 |  |
          * @param datasource    the datasource to connect to the database
130 |  |
          * @param table         the name of the table containing the configurations
131 |  |
          * @param keyColumn     the column containing the keys of the configuration
132 |  |
          * @param valueColumn   the column containing the values of the configuration
133 |  |
          */
134 |  |
         public DatabaseConfiguration(DataSource datasource, String table, String keyColumn, String valueColumn)
135 |  |
         {
136 | 22 |
             this(datasource, table, null, keyColumn, valueColumn, null);
137 | 22 |
         }
138 |  |
139 |  |
         /**
140 |  |
          * Returns the value of the specified property. If this causes a database
141 |  |
          * error, an error event will be generated of type
142 |  |
          * <code>EVENT_READ_PROPERTY</code> with the causing exception. The
143 |  |
          * event's <code>propertyName</code> is set to the passed in property key,
144 |  |
          * the <code>propertyValue</code> is undefined.
145 |  |
          *
146 |  |
          * @param key the key of the desired property
147 |  |
          * @return the value of this property
148 |  |
          */
149 |  |
         public Object getProperty(String key)
150 |  |
         {
151 | 11 |
             Object result = null;
152 |  |
153 |  |
             // build the query
154 | 11 |
             StringBuffer query = new StringBuffer("SELECT * FROM ");
155 | 11 |
             query.append(table).append(" WHERE ");
156 | 11 |
             query.append(keyColumn).append("=?");
157 | 11 |
             if (nameColumn != null)
158 |  |
             {
159 | 3 |
                 query.append(" AND " + nameColumn + "=?");
160 |  |
             }
161 |  |
162 | 11 |
             Connection conn = null;
163 | 11 |
             PreparedStatement pstmt = null;
164 |  |
165 |  |
             try
166 |  |
             {
167 | 11 |
                 conn = getConnection();
168 |  |
169 |  |
                 // bind the parameters
170 | 10 |
                 pstmt = conn.prepareStatement(query.toString());
171 | 10 |
                 pstmt.setString(1, key);
172 | 10 |
                 if (nameColumn != null)
173 |  |
                 {
174 | 3 |
                     pstmt.setString(2, name);
175 |  |
                 }
176 |  |
177 | 10 |
                 ResultSet rs = pstmt.executeQuery();
178 |  |
179 | 10 |
                 List results = new ArrayList();
180 | 20 |
                 while (rs.next())
181 |  |
                 {
182 | 10 |
                     Object value = rs.getObject(valueColumn);
183 | 10 |
                     if (isDelimiterParsingDisabled())
184 |  |
                     {
185 | 1 |
                         results.add(value);
186 | 1 |
                     }
187 |  |
                     else
188 |  |
                     {
189 |  |
                         // Split value if it containts the list delimiter
190 | 9 |
                         CollectionUtils.addAll(results, PropertyConverter.toIterator(value, getListDelimiter()));
191 |  |
                     }
192 | 10 |
                 }
193 |  |
194 | 10 |
                 if (!results.isEmpty())
195 |  |
                 {
196 | 8 |
                     result = (results.size() > 1) ? results : results.get(0);
197 |  |
                 }
198 |  |
             }
199 | 1 |
             catch (SQLException e)
200 |  |
             {
201 | 1 |
                 fireError(EVENT_READ_PROPERTY, key, null, e);
202 |  |
             }
203 |  |
             finally
204 |  |
             {
205 | 11 |
                 close(conn, pstmt);
206 | 11 |
             }
207 |  |
208 | 11 |
             return result;
209 |  |
         }
210 |  |
211 |  |
         /**
212 |  |
          * Adds a property to this configuration. If this causes a database error,
213 |  |
          * an error event will be generated of type <code>EVENT_ADD_PROPERTY</code>
214 |  |
          * with the causing exception. The event's <code>propertyName</code> is
215 |  |
          * set to the passed in property key, the <code>propertyValue</code>
216 |  |
          * points to the passed in value.
217 |  |
          *
218 |  |
          * @param key the property key
219 |  |
          * @param obj the value of the property to add
220 |  |
          */
221 |  |
         protected void addPropertyDirect(String key, Object obj)
222 |  |
         {
223 |  |
             // build the query
224 | 5 |
             StringBuffer query = new StringBuffer("INSERT INTO " + table);
225 | 5 |
             if (nameColumn != null)
226 |  |
             {
227 | 1 |
                 query.append(" (" + nameColumn + ", " + keyColumn + ", " + valueColumn + ") VALUES (?, ?, ?)");
228 | 1 |
             }
229 |  |
             else
230 |  |
             {
231 | 4 |
                 query.append(" (" + keyColumn + ", " + valueColumn + ") VALUES (?, ?)");
232 |  |
             }
233 |  |
234 | 5 |
             Connection conn = null;
235 | 5 |
             PreparedStatement pstmt = null;
236 |  |
237 |  |
             try
238 |  |
             {
239 | 5 |
                 conn = getConnection();
240 |  |
241 |  |
                 // bind the parameters
242 | 4 |
                 pstmt = conn.prepareStatement(query.toString());
243 | 4 |
                 int index = 1;
244 | 4 |
                 if (nameColumn != null)
245 |  |
                 {
246 | 1 |
                     pstmt.setString(index++, name);
247 |  |
                 }
248 | 4 |
                 pstmt.setString(index++, key);
249 | 4 |
                 pstmt.setString(index++, String.valueOf(obj));
250 |  |
251 | 4 |
                 pstmt.executeUpdate();
252 |  |
             }
253 | 1 |
             catch (SQLException e)
254 |  |
             {
255 | 1 |
                 fireError(EVENT_ADD_PROPERTY, key, obj, e);
256 |  |
             }
257 |  |
             finally
258 |  |
             {
259 |  |
                 // clean up
260 | 5 |
                 close(conn, pstmt);
261 | 5 |
             }
262 | 5 |
         }
263 |  |
264 |  |
         /**
265 |  |
          * Adds a property to this configuration. This implementation will
266 |  |
          * temporarily disable list delimiter parsing, so that even if the value
267 |  |
          * contains the list delimiter, only a single record will be written into
268 |  |
          * the managed table. The implementation of <code>getProperty()</code>
269 |  |
          * will take care about delimiters. So list delimiters are fully supported
270 |  |
          * by <code>DatabaseConfiguration</code>, but internally treated a bit
271 |  |
          * differently.
272 |  |
          *
273 |  |
          * @param key the key of the new property
274 |  |
          * @param value the value to be added
275 |  |
          */
276 |  |
         public void addProperty(String key, Object value)
277 |  |
         {
278 | 2 |
             boolean parsingFlag = isDelimiterParsingDisabled();
279 |  |
             try
280 |  |
             {
281 | 2 |
                 if (value instanceof String)
282 |  |
                 {
283 |  |
                     // temporarily disable delimiter parsing
284 | 2 |
                     setDelimiterParsingDisabled(true);
285 |  |
                 }
286 | 2 |
                 super.addProperty(key, value);
287 |  |
             }
288 |  |
             finally
289 |  |
             {
290 | 2 |
                 setDelimiterParsingDisabled(parsingFlag);
291 | 2 |
             }
292 | 2 |
         }
293 |  |
294 |  |
         /**
295 |  |
          * Checks if this configuration is empty. If this causes a database error,
296 |  |
          * an error event will be generated of type <code>EVENT_READ_PROPERTY</code>
297 |  |
          * with the causing exception. Both the event's <code>propertyName</code>
298 |  |
          * and <code>propertyValue</code> will be undefined.
299 |  |
          *
300 |  |
          * @return a flag whether this configuration is empty.
301 |  |
          */
302 |  |
         public boolean isEmpty()
303 |  |
         {
304 | 7 |
             boolean empty = true;
305 |  |
306 |  |
             // build the query
307 | 7 |
             StringBuffer query = new StringBuffer("SELECT count(*) FROM " + table);
308 | 7 |
             if (nameColumn != null)
309 |  |
             {
310 | 3 |
                 query.append(" WHERE " + nameColumn + "=?");
311 |  |
             }
312 |  |
313 | 7 |
             Connection conn = null;
314 | 7 |
             PreparedStatement pstmt = null;
315 |  |
316 |  |
             try
317 |  |
             {
318 | 7 |
                 conn = getConnection();
319 |  |
320 |  |
                 // bind the parameters
321 | 6 |
                 pstmt = conn.prepareStatement(query.toString());
322 | 6 |
                 if (nameColumn != null)
323 |  |
                 {
324 | 3 |
                     pstmt.setString(1, name);
325 |  |
                 }
326 |  |
327 | 6 |
                 ResultSet rs = pstmt.executeQuery();
328 |  |
329 | 6 |
                 if (rs.next())
330 |  |
                 {
331 | 6 |
                     empty = rs.getInt(1) == 0;
332 |  |
                 }
333 |  |
             }
334 | 1 |
             catch (SQLException e)
335 |  |
             {
336 | 1 |
                 fireError(EVENT_READ_PROPERTY, null, null, e);
337 |  |
             }
338 |  |
             finally
339 |  |
             {
340 |  |
                 // clean up
341 | 7 |
                 close(conn, pstmt);
342 | 7 |
             }
343 |  |
344 | 7 |
             return empty;
345 |  |
         }
346 |  |
347 |  |
         /**
348 |  |
          * Checks whether this configuration contains the specified key. If this
349 |  |
          * causes a database error, an error event will be generated of type
350 |  |
          * <code>EVENT_READ_PROPERTY</code> with the causing exception. The
351 |  |
          * event's <code>propertyName</code> will be set to the passed in key, the
352 |  |
          * <code>propertyValue</code> will be undefined.
353 |  |
          *
354 |  |
          * @param key the key to be checked
355 |  |
          * @return a flag whether this key is defined
356 |  |
          */
357 |  |
         public boolean containsKey(String key)
358 |  |
         {
359 | 11 |
             boolean found = false;
360 |  |
361 |  |
             // build the query
362 | 11 |
             StringBuffer query = new StringBuffer("SELECT * FROM " + table + " WHERE " + keyColumn + "=?");
363 | 11 |
             if (nameColumn != null)
364 |  |
             {
365 | 4 |
                 query.append(" AND " + nameColumn + "=?");
366 |  |
             }
367 |  |
368 | 11 |
             Connection conn = null;
369 | 11 |
             PreparedStatement pstmt = null;
370 |  |
371 |  |
             try
372 |  |
             {
373 | 11 |
                 conn = getConnection();
374 |  |
375 |  |
                 // bind the parameters
376 | 10 |
                 pstmt = conn.prepareStatement(query.toString());
377 | 10 |
                 pstmt.setString(1, key);
378 | 10 |
                 if (nameColumn != null)
379 |  |
                 {
380 | 4 |
                     pstmt.setString(2, name);
381 |  |
                 }
382 |  |
383 | 10 |
                 ResultSet rs = pstmt.executeQuery();
384 |  |
385 | 10 |
                 found = rs.next();
386 |  |
             }
387 | 1 |
             catch (SQLException e)
388 |  |
             {
389 | 1 |
                 fireError(EVENT_READ_PROPERTY, key, null, e);
390 |  |
             }
391 |  |
             finally
392 |  |
             {
393 |  |
                 // clean up
394 | 11 |
                 close(conn, pstmt);
395 | 11 |
             }
396 |  |
397 | 11 |
             return found;
398 |  |
         }
399 |  |
400 |  |
         /**
401 |  |
          * Removes the specified value from this configuration. If this causes a
402 |  |
          * database error, an error event will be generated of type
403 |  |
          * <code>EVENT_CLEAR_PROPERTY</code> with the causing exception. The
404 |  |
          * event's <code>propertyName</code> will be set to the passed in key, the
405 |  |
          * <code>propertyValue</code> will be undefined.
406 |  |
          *
407 |  |
          * @param key the key of the property to be removed
408 |  |
          */
409 |  |
         public void clearProperty(String key)
410 |  |
         {
411 |  |
             // build the query
412 | 4 |
             StringBuffer query = new StringBuffer("DELETE FROM " + table + " WHERE " + keyColumn + "=?");
413 | 4 |
             if (nameColumn != null)
414 |  |
             {
415 | 1 |
                 query.append(" AND " + nameColumn + "=?");
416 |  |
             }
417 |  |
418 | 4 |
             Connection conn = null;
419 | 4 |
             PreparedStatement pstmt = null;
420 |  |
421 |  |
             try
422 |  |
             {
423 | 4 |
                 conn = getConnection();
424 |  |
425 |  |
                 // bind the parameters
426 | 3 |
                 pstmt = conn.prepareStatement(query.toString());
427 | 3 |
                 pstmt.setString(1, key);
428 | 3 |
                 if (nameColumn != null)
429 |  |
                 {
430 | 1 |
                     pstmt.setString(2, name);
431 |  |
                 }
432 |  |
433 | 3 |
                 pstmt.executeUpdate();
434 |  |
             }
435 | 1 |
             catch (SQLException e)
436 |  |
             {
437 | 1 |
                 fireError(EVENT_CLEAR_PROPERTY, key, null, e);
438 |  |
             }
439 |  |
             finally
440 |  |
             {
441 |  |
                 // clean up
442 | 4 |
                 close(conn, pstmt);
443 | 4 |
             }
444 | 4 |
         }
445 |  |
446 |  |
         /**
447 |  |
          * Removes all entries from this configuration. If this causes a database
448 |  |
          * error, an error event will be generated of type
449 |  |
          * <code>EVENT_CLEAR</code> with the causing exception. Both the
450 |  |
          * event's <code>propertyName</code> and the <code>propertyValue</code>
451 |  |
          * will be undefined.
452 |  |
          */
453 |  |
         public void clear()
454 |  |
         {
455 |  |
             // build the query
456 | 3 |
             StringBuffer query = new StringBuffer("DELETE FROM " + table);
457 | 3 |
             if (nameColumn != null)
458 |  |
             {
459 | 1 |
                 query.append(" WHERE " + nameColumn + "=?");
460 |  |
             }
461 |  |
462 | 3 |
             Connection conn = null;
463 | 3 |
             PreparedStatement pstmt = null;
464 |  |
465 |  |
             try
466 |  |
             {
467 | 3 |
                 conn = getConnection();
468 |  |
469 |  |
                 // bind the parameters
470 | 2 |
                 pstmt = conn.prepareStatement(query.toString());
471 | 2 |
                 if (nameColumn != null)
472 |  |
                 {
473 | 1 |
                     pstmt.setString(1, name);
474 |  |
                 }
475 |  |
476 | 2 |
                 pstmt.executeUpdate();
477 |  |
             }
478 | 1 |
             catch (SQLException e)
479 |  |
             {
480 | 1 |
                 fireError(EVENT_CLEAR, null, null, e);
481 |  |
             }
482 |  |
             finally
483 |  |
             {
484 |  |
                 // clean up
485 | 3 |
                 close(conn, pstmt);
486 | 3 |
             }
487 | 3 |
         }
488 |  |
489 |  |
         /**
490 |  |
          * Returns an iterator with the names of all properties contained in this
491 |  |
          * configuration. If this causes a database
492 |  |
          * error, an error event will be generated of type
493 |  |
          * <code>EVENT_READ_PROPERTY</code> with the causing exception. Both the
494 |  |
          * event's <code>propertyName</code> and the <code>propertyValue</code>
495 |  |
          * will be undefined.
496 |  |
          * @return an iterator with the contained keys (an empty iterator in case
497 |  |
          * of an error)
498 |  |
          */
499 |  |
         public Iterator getKeys()
500 |  |
         {
501 | 6 |
             Collection keys = new ArrayList();
502 |  |
503 |  |
             // build the query
504 | 6 |
             StringBuffer query = new StringBuffer("SELECT DISTINCT " + keyColumn + " FROM " + table);
505 | 6 |
             if (nameColumn != null)
506 |  |
             {
507 | 1 |
                 query.append(" WHERE " + nameColumn + "=?");
508 |  |
             }
509 |  |
510 | 6 |
             Connection conn = null;
511 | 6 |
             PreparedStatement pstmt = null;
512 |  |
513 |  |
             try
514 |  |
             {
515 | 6 |
                 conn = getConnection();
516 |  |
517 |  |
                 // bind the parameters
518 | 5 |
                 pstmt = conn.prepareStatement(query.toString());
519 | 5 |
                 if (nameColumn != null)
520 |  |
                 {
521 | 1 |
                     pstmt.setString(1, name);
522 |  |
                 }
523 |  |
524 | 5 |
                 ResultSet rs = pstmt.executeQuery();
525 |  |
526 | 16 |
                 while (rs.next())
527 |  |
                 {
528 | 11 |
                     keys.add(rs.getString(1));
529 | 11 |
                 }
530 |  |
             }
531 | 1 |
             catch (SQLException e)
532 |  |
             {
533 | 1 |
                 fireError(EVENT_READ_PROPERTY, null, null, e);
534 |  |
             }
535 |  |
             finally
536 |  |
             {
537 |  |
                 // clean up
538 | 6 |
                 close(conn, pstmt);
539 | 6 |
             }
540 |  |
541 | 6 |
             return keys.iterator();
542 |  |
         }
543 |  |
544 |  |
         /**
545 |  |
          * Returns the used <code>DataSource</code> object.
546 |  |
          *
547 |  |
          * @return the data source
548 |  |
          * @since 1.4
549 |  |
          */
550 |  |
         public DataSource getDatasource()
551 |  |
         {
552 | 40 |
             return datasource;
553 |  |
         }
554 |  |
555 |  |
         /**
556 |  |
          * Returns a <code>Connection</code> object. This method is called when
557 |  |
          * ever the database is to be accessed. This implementation returns a
558 |  |
          * connection from the current <code>DataSource</code>.
559 |  |
          *
560 |  |
          * @return the <code>Connection</code> object to be used
561 |  |
          * @throws SQLException if an error occurs
562 |  |
          * @since 1.4
563 |  |
          * @deprecated Use a custom data source to change the connection used by the
564 |  |
          * class. To be removed in Commons Configuration 2.0
565 |  |
          */
566 |  |
         protected Connection getConnection() throws SQLException
567 |  |
         {
568 | 40 |
             return getDatasource().getConnection();
569 |  |
         }
570 |  |
571 |  |
         /**
572 |  |
          * Close a <code>Connection</code> and, <code>Statement</code>.
573 |  |
          * Avoid closing if null and hide any SQLExceptions that occur.
574 |  |
          *
575 |  |
          * @param conn The database connection to close
576 |  |
          * @param stmt The statement to close
577 |  |
          */
578 |  |
         private void close(Connection conn, Statement stmt)
579 |  |
         {
580 |  |
             try
581 |  |
             {
582 | 47 |
                 if (stmt != null)
583 |  |
                 {
584 | 40 |
                     stmt.close();
585 |  |
                 }
586 |  |
             }
587 | 0 |
             catch (SQLException e)
588 |  |
             {
589 | 0 |
                 getLogger().error("An error occured on closing the statement", e);
590 | 47 |
             }
591 |  |
592 |  |
             try
593 |  |
             {
594 | 47 |
                 if (conn != null)
595 |  |
                 {
596 | 40 |
                     conn.close();
597 |  |
                 }
598 |  |
             }
599 | 0 |
             catch (SQLException e)
600 |  |
             {
601 | 0 |
                 getLogger().error("An error occured on closing the connection", e);
602 | 47 |
             }
603 | 47 |
         }
604 |  |
     }