1 package org.apache.torque;
2
3 /* ====================================================================
4 * The Apache Software License, Version 1.1
5 *
6 * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
7 * reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. The end-user documentation included with the redistribution,
22 * if any, must include the following acknowledgment:
23 * "This product includes software developed by the
24 * Apache Software Foundation (http://www.apache.org/)."
25 * Alternately, this acknowledgment may appear in the software itself,
26 * if and wherever such third-party acknowledgments normally appear.
27 *
28 * 4. The names "Apache" and "Apache Software Foundation" and
29 * "Apache Turbine" must not be used to endorse or promote products
30 * derived from this software without prior written permission. For
31 * written permission, please contact apache@apache.org.
32 *
33 * 5. Products derived from this software may not be called "Apache",
34 * "Apache Turbine", nor may "Apache" appear in their name, without
35 * prior written permission of the Apache Software Foundation.
36 *
37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 * SUCH DAMAGE.
49 * ====================================================================
50 *
51 * This software consists of voluntary contributions made by many
52 * individuals on behalf of the Apache Software Foundation. For more
53 * information on the Apache Software Foundation, please see
54 * <http://www.apache.org/>.
55 */
56
57 import java.io.IOException;
58 import java.sql.Connection;
59 import java.sql.SQLException;
60 import java.util.ArrayList;
61 import java.util.Collections;
62 import java.util.HashMap;
63 import java.util.Iterator;
64 import java.util.List;
65 import java.util.Map;
66
67 import org.apache.commons.configuration.Configuration;
68 import org.apache.commons.configuration.PropertiesConfiguration;
69
70 import org.apache.commons.logging.Log;
71 import org.apache.commons.logging.LogFactory;
72
73 import org.apache.torque.adapter.DB;
74 import org.apache.torque.adapter.DBFactory;
75 import org.apache.torque.dsfactory.DataSourceFactory;
76 import org.apache.torque.manager.AbstractBaseManager;
77 import org.apache.torque.map.DatabaseMap;
78 import org.apache.torque.map.TableMap;
79 import org.apache.torque.oid.IDBroker;
80 import org.apache.torque.oid.IDGeneratorFactory;
81 import org.apache.torque.util.BasePeer;
82
83 /***
84 * The core of Torque's implementation. Both the classic {@link
85 * org.apache.torque.Torque} static wrapper and the {@link
86 * org.apache.torque.avalon.TorqueComponent} <a
87 * href="http://avalon.apache.org/">Avalon</a> implementation leverage
88 * this class.
89 *
90 * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
91 * @author <a href="mailto:magnus@handtolvur.is">Magnús Þór Torfason</a>
92 * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
93 * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
94 * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
95 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
96 * @author <a href="mailto:kschrader@karmalab.org">Kurt Schrader</a>
97 * @version $Id: TorqueInstance.java,v 1.5 2003/08/05 18:09:35 mpoeschl Exp $
98 */
99 public class TorqueInstance
100 {
101 /*** Logging */
102 private static Log log = LogFactory.getLog(TorqueInstance.class);
103
104 /*** A constant for <code>default</code>. */
105 private static final String DEFAULT_NAME = "default";
106
107 /*** The db name that is specified as the default in the property file */
108 private String defaultDBName;
109
110 /*** The global cache of database maps */
111 private Map dbMaps;
112
113 /*** The cache of DataSourceFactory's */
114 private Map dsFactoryMap;
115
116 /*** The cache of DB adapter keys */
117 private Map adapterMap;
118
119 /*** A repository of Manager instances. */
120 private Map managers;
121
122 /*** Torque-specific configuration. */
123 private Configuration conf;
124
125 /*** flag to set to true once this class has been initialized */
126 private boolean isInit = false;
127
128 /***
129 * Store mapbuilder classnames for peers that have been referenced prior
130 * to Torque being initialized. This can happen if torque om/peer objects
131 * are serialized then unserialized prior to Torque being reinitialized.
132 * This condition exists in a normal catalina restart.
133 */
134 private List mapBuilders = null;
135
136 /***
137 * Creates a new instance with default configuration.
138 *
139 * @see #resetConfiguration()
140 */
141 public TorqueInstance()
142 {
143 resetConfiguration();
144 }
145
146 /***
147 * Initializes this instance of Torque.
148 *
149 * @see org.apache.stratum.lifecycle.Initializable
150 * @throws TorqueException Any exceptions caught during processing will be
151 * rethrown wrapped into a TorqueException.
152 */
153 private synchronized void initialize() throws TorqueException
154 {
155 log.debug("initialize()");
156
157 if (isInit)
158 {
159 log.debug("Multiple initializations of Torque attempted");
160 return;
161 }
162
163 if (conf == null)
164 {
165 throw new TorqueException("Torque cannot be initialized without "
166 + "a valid configuration. Please check the log files "
167 + "for further details.");
168 }
169
170 // Now that we have dealt with processing the log4j properties
171 // that may be contained in the configuration we will make the
172 // configuration consist only of the remain torque specific
173 // properties that are contained in the configuration. First
174 // look for properties that are in the "torque" namespace.
175
176 Configuration subConf = conf.subset("torque");
177
178 if (!subConf.isEmpty())
179 {
180 setConfiguration(subConf);
181 }
182
183 dbMaps = new HashMap();
184 initAdapters(conf);
185 initDataSourceFactories(conf);
186
187 for (Iterator i = mapBuilders.iterator(); i.hasNext();)
188 {
189 //this will add any maps in this builder to the proper database map
190 BasePeer.getMapBuilder((String) i.next());
191 }
192 // any further mapBuilders will be called/built on demand
193 mapBuilders = null;
194
195 // setup manager mappings
196 initManagerMappings(conf);
197
198 isInit = true;
199 }
200
201 /***
202 *
203 * @param conf the Configuration representing the properties file
204 * @throws TorqueException Any exceptions caught during processing will be
205 * rethrown wrapped into a TorqueException.
206 */
207 private final void initAdapters(Configuration conf)
208 throws TorqueException
209 {
210 log.debug("initAdapters(" + conf + ")");
211 adapterMap = new HashMap();
212 Configuration c = conf.subset("database");
213
214 if (c != null)
215 {
216 boolean foundAdapters = false;
217
218 try
219 {
220 for (Iterator it = c.getKeys(); it.hasNext(); )
221 {
222 String key = (String) it.next();
223 if (key.endsWith("adapter"))
224 {
225 String adapter = c.getString(key);
226 String handle = key.substring(0, key.indexOf('.'));
227 DB db = DBFactory.create(adapter);
228 // register the adapter for this name
229 adapterMap.put(handle, db);
230 log.debug("Adding " + adapter + " -> " + handle + " as Adapter");
231 foundAdapters = true;
232 }
233 }
234 if (!foundAdapters)
235 {
236 log.warn("Databases defined but no adapter "
237 + "configurations found!");
238 }
239 }
240 catch (Exception e)
241 {
242 log.error("Error reading configuration seeking database "
243 + "adapters", e);
244 throw new TorqueException(e);
245 }
246 }
247 else
248 {
249 log.warn("No Database definitions found!");
250 }
251
252 }
253
254 /***
255 *
256 * @param conf the Configuration representing the properties file
257 * @throws TorqueException Any exceptions caught during processing will be
258 * rethrown wrapped into a TorqueException.
259 */
260 private void initDataSourceFactories(Configuration conf)
261 throws TorqueException
262 {
263 log.debug("initDataSourceFactories(" + conf + ")");
264 dsFactoryMap = new HashMap();
265 Configuration c = conf.subset("dsfactory");
266 if (c != null)
267 {
268 boolean foundFactories = false;
269
270 try
271 {
272 for (Iterator it = c.getKeys(); it.hasNext();)
273 {
274 String key = (String) it.next();
275 if (key.endsWith("factory"))
276 {
277 String classname = c.getString(key);
278 String handle = key.substring(0, key.indexOf('.'));
279 log.debug("handle: " + handle
280 + " DataSourceFactory: " + classname);
281 Class dsfClass = Class.forName(classname);
282 DataSourceFactory dsf =
283 (DataSourceFactory) dsfClass.newInstance();
284 dsf.initialize(c.subset(handle));
285 dsFactoryMap.put(handle, dsf);
286 foundFactories = true;
287 }
288 }
289 if (!foundFactories)
290 {
291 log.warn("Data Sources configured but no factories found!");
292 }
293 }
294 catch (Exception e)
295 {
296 log.error("Error reading adapter configuration", e);
297 throw new TorqueException(e);
298 }
299 }
300
301 // As there might be a default database configured
302 // to map "default" onto an existing datasource, we
303 // must check, whether there _is_ really an entry for
304 // the "default" in the dsFactoryMap or not. If it is
305 // not, then add a dummy entry for the "default"
306 //
307 // Without this, you can't actually access the "default"
308 // data-source, even if you have an entry like
309 //
310 // database.default = bookstore
311 //
312 // in your Torque.properties
313 //
314 String defaultDB = getDefaultDB();
315
316 if (dsFactoryMap.get(DEFAULT_NAME) == null
317 && !defaultDB.equals(DEFAULT_NAME))
318 {
319 log.debug("Adding a dummy entry for "
320 + DEFAULT_NAME + ", mapped onto " + defaultDB);
321 dsFactoryMap.put(DEFAULT_NAME, dsFactoryMap.get(defaultDB));
322 }
323 }
324
325 /***
326 * Initialization of Torque with a properties file.
327 *
328 * @param configFile The absolute path to the configuration file.
329 * @throws TorqueException Any exceptions caught during processing will be
330 * rethrown wrapped into a TorqueException.
331 */
332 public void init(String configFile)
333 throws TorqueException
334 {
335 log.debug("init(" + configFile + ")");
336 try
337 {
338 Configuration conf = (Configuration)
339 new PropertiesConfiguration(configFile);
340
341 log.debug("Config Object is " + conf);
342 init(conf);
343 }
344 catch (IOException e)
345 {
346 throw new TorqueException(e);
347 }
348 }
349
350 /***
351 * Initialization of Torque with a properties file.
352 *
353 * @param conf The Torque configuration.
354 * @throws TorqueException Any exceptions caught during processing will be
355 * rethrown wrapped into a TorqueException.
356 */
357 public void init(Configuration conf)
358 throws TorqueException
359 {
360 log.debug("init(" + conf + ")");
361 setConfiguration(conf);
362 initialize();
363 }
364
365
366 /***
367 * Creates a mapping between classes and their manager classes.
368 *
369 * The mapping is built according to settings present in
370 * properties file. The entries should have the
371 * following form:
372 *
373 * <pre>
374 * torque.managed_class.com.mycompany.Myclass.manager= \
375 * com.mycompany.MyManagerImpl
376 * services.managed_class.com.mycompany.Myotherclass.manager= \
377 * com.mycompany.MyOtherManagerImpl
378 * </pre>
379 *
380 * <br>
381 *
382 * Generic ServiceBroker provides no Services.
383 *
384 * @param conf the Configuration representing the properties file
385 * @throws TorqueException Any exceptions caught during processing will be
386 * rethrown wrapped into a TorqueException.
387 */
388 protected void initManagerMappings(Configuration conf)
389 throws TorqueException
390 {
391 int pref = Torque.MANAGER_PREFIX.length();
392 int suff = Torque.MANAGER_SUFFIX.length();
393
394 for (Iterator it = conf.getKeys(); it.hasNext();)
395 {
396 String key = (String) it.next();
397
398 if (key.startsWith(Torque.MANAGER_PREFIX)
399 && key.endsWith(Torque.MANAGER_SUFFIX))
400 {
401 String managedClassKey = key.substring(pref,
402 key.length() - suff);
403 if (!managers.containsKey(managedClassKey))
404 {
405 String managerClass = conf.getString(key);
406 log.info("Added Manager for Class: " + managedClassKey
407 + " -> " + managerClass);
408 try
409 {
410 initManager(managedClassKey, managerClass);
411 }
412 catch (TorqueException e)
413 {
414 // the exception thrown here seems to disappear.
415 // At least when initialized by Turbine, should find
416 // out why, but for now make sure it is noticed.
417 log.error("", e);
418 e.printStackTrace();
419 throw e;
420 }
421 }
422 }
423 }
424 }
425
426 /***
427 * Initialize a manager
428 *
429 * @param name name of the manager
430 * @param className name of the manager class
431 * @throws TorqueException Any exceptions caught during processing will be
432 * rethrown wrapped into a TorqueException.
433 */
434 private synchronized void initManager(String name, String className)
435 throws TorqueException
436 {
437 AbstractBaseManager manager = (AbstractBaseManager) managers.get(name);
438
439 if (manager == null)
440 {
441 if (className != null && className.length() != 0)
442 {
443 try
444 {
445 manager = (AbstractBaseManager)
446 Class.forName(className).newInstance();
447 managers.put(name, manager);
448 }
449 catch (Exception e)
450 {
451 throw new TorqueException("Could not instantiate "
452 + "manager associated with class: "
453 + name, e);
454 }
455 }
456 }
457 }
458
459 /***
460 * Determine whether Torque has already been initialized.
461 *
462 * @return true if Torque is already initialized
463 */
464 public boolean isInit()
465 {
466 return isInit;
467 }
468
469 /***
470 * Sets the configuration for Torque and all dependencies.
471 *
472 * @param conf the Configuration
473 */
474 public void setConfiguration(Configuration conf)
475 {
476 log.debug("setConfiguration(" + conf + ")");
477 this.conf = conf;
478 }
479
480 /***
481 * Get the configuration for this component.
482 *
483 * @return the Configuration
484 */
485 public Configuration getConfiguration()
486 {
487 log.debug("getConfiguration() = " + conf);
488 return conf;
489 }
490
491 /***
492 * This method returns a Manager for the given name.
493 *
494 * @param name name of the manager
495 * @return a Manager
496 */
497 public AbstractBaseManager getManager(String name)
498 {
499 AbstractBaseManager m = (AbstractBaseManager) managers.get(name);
500 if (m == null)
501 {
502 log.error("No configured manager for key " + name + ".");
503 }
504 return m;
505 }
506
507 /***
508 * This methods returns either the Manager from the configuration file,
509 * or the default one provided by the generated code.
510 *
511 * @param name name of the manager
512 * @param defaultClassName the class to use if name has not been configured
513 * @return a Manager
514 */
515 public AbstractBaseManager getManager(String name,
516 String defaultClassName)
517 {
518 AbstractBaseManager m = (AbstractBaseManager) managers.get(name);
519 if (m == null)
520 {
521 log.debug("Added late Manager mapping for Class: "
522 + name + " -> " + defaultClassName);
523
524 try
525 {
526 initManager(name, defaultClassName);
527 }
528 catch (TorqueException e)
529 {
530 log.error(e.getMessage(), e);
531 }
532
533 // Try again now that the default manager should be in the map
534 m = (AbstractBaseManager) managers.get(name);
535 }
536
537 return m;
538 }
539
540 /***
541 * Shuts down the service.
542 *
543 * This method halts the IDBroker's daemon thread in all of
544 * the DatabaseMap's.
545 */
546 public synchronized void shutdown()
547 {
548 if (dbMaps != null)
549 {
550 for (Iterator it = dbMaps.values().iterator(); it.hasNext();)
551 {
552 DatabaseMap map = (DatabaseMap) it.next();
553 IDBroker idBroker = map.getIDBroker();
554 if (idBroker != null)
555 {
556 idBroker.stop();
557 }
558 }
559 }
560 resetConfiguration();
561 }
562
563 /***
564 * Resets some internal configuration variables to
565 * their defaults.
566 */
567 private void resetConfiguration()
568 {
569 mapBuilders = Collections.synchronizedList(new ArrayList());
570 managers = new HashMap();
571 isInit = false;
572 }
573
574 /***
575 * Returns the default database map information.
576 *
577 * @return A DatabaseMap.
578 * @throws TorqueException Any exceptions caught during processing will be
579 * rethrown wrapped into a TorqueException.
580 */
581 public DatabaseMap getDatabaseMap()
582 throws TorqueException
583 {
584 return getDatabaseMap(getDefaultDB());
585 }
586
587 /***
588 * Returns the database map information. Name relates to the name
589 * of the connection pool to associate with the map.
590 *
591 * @param name The name of the database corresponding to the
592 * <code>DatabaseMap</code> to retrieve.
593 * @return The named <code>DatabaseMap</code>.
594 * @throws TorqueException Any exceptions caught during processing will be
595 * rethrown wrapped into a TorqueException.
596 */
597 public DatabaseMap getDatabaseMap(String name)
598 throws TorqueException
599 {
600 if (name == null)
601 {
602 throw new TorqueException ("DatabaseMap name was null!");
603 }
604
605 if (dbMaps == null)
606 {
607 throw new TorqueException("Torque was not initialized properly.");
608 }
609
610 synchronized (dbMaps)
611 {
612 DatabaseMap map = (DatabaseMap) dbMaps.get(name);
613 if (map == null)
614 {
615 // Still not there. Create and add.
616 map = initDatabaseMap(name);
617 }
618 return map;
619 }
620 }
621
622 /***
623 * Creates and initializes the mape for the named database.
624 * Assumes that <code>dbMaps</code> member is sync'd.
625 *
626 * @param name The name of the database to map.
627 * @return The desired map.
628 * @throws TorqueException Any exceptions caught during processing will be
629 * rethrown wrapped into a TorqueException.
630 */
631 private final DatabaseMap initDatabaseMap(String name)
632 throws TorqueException
633 {
634 DatabaseMap map = new DatabaseMap(name);
635
636 // Add info about IDBroker's table.
637 setupIdTable(map);
638
639 // Setup other ID generators for this map.
640 try
641 {
642 String key = getDatabaseProperty(name, "driver");
643 if (key == null || key.length() == 0)
644 {
645 key = getDatabaseProperty(name, "adapter");
646 }
647 DB db = DBFactory.create(key);
648 for (int i = 0; i < IDGeneratorFactory.ID_GENERATOR_METHODS.length;
649 i++)
650 {
651 map.addIdGenerator(IDGeneratorFactory.ID_GENERATOR_METHODS[i],
652 IDGeneratorFactory.create(db));
653 }
654 }
655 catch (java.lang.InstantiationException e)
656 {
657 throw new TorqueException(e);
658 }
659
660 // Avoid possible ConcurrentModificationException by
661 // constructing a copy of dbMaps.
662 Map newMaps = new HashMap(dbMaps);
663 newMaps.put(name, map);
664 dbMaps = newMaps;
665
666 return map;
667 }
668
669 /***
670 * Register a MapBuilder
671 *
672 * @param className the MapBuilder
673 */
674 public void registerMapBuilder(String className)
675 {
676 mapBuilders.add(className);
677 }
678
679 /***
680 * Returns the specified property of the given database, or the empty
681 * string if no value is set for the property.
682 *
683 * @param db The name of the database whose property to get.
684 * @param prop The name of the property to get.
685 * @return The property's value.
686 */
687 private String getDatabaseProperty(String db, String prop)
688 {
689 return conf.getString(new StringBuffer("database.")
690 .append(db)
691 .append('.')
692 .append(prop)
693 .toString(), "");
694 }
695
696 /***
697 * Setup IDBroker's table information within given database map.
698 *
699 * This method should be called on all new database map to ensure that
700 * IDBroker functionality is available in all databases used by the
701 * application.
702 *
703 * @param map the DataBaseMap to setup.
704 */
705 private final void setupIdTable(DatabaseMap map)
706 {
707 map.setIdTable("ID_TABLE");
708 TableMap tMap = map.getIdTable();
709 tMap.addPrimaryKey("ID_TABLE_ID", new Integer(0));
710 tMap.addColumn("TABLE_NAME", "");
711 tMap.addColumn("NEXT_ID", new Integer(0));
712 tMap.addColumn("QUANTITY", new Integer(0));
713 }
714
715 /***
716 * This method returns a Connection from the default pool.
717 *
718 * @return The requested connection.
719 * @throws TorqueException Any exceptions caught during processing will be
720 * rethrown wrapped into a TorqueException.
721 */
722 public Connection getConnection()
723 throws TorqueException
724 {
725 return getConnection(getDefaultDB());
726 }
727
728 /***
729 *
730 * @param name The database name.
731 * @return a database connection
732 * @throws TorqueException Any exceptions caught during processing will be
733 * rethrown wrapped into a TorqueException.
734 */
735 public Connection getConnection(String name)
736 throws TorqueException
737 {
738 Connection con = null;
739 DataSourceFactory dsf = null;
740 try
741 {
742 dsf = (DataSourceFactory) dsFactoryMap.get(name);
743 con = dsf.getDataSource().getConnection();
744 }
745 catch (Exception e)
746 {
747 if (dsf == null && e instanceof NullPointerException)
748 {
749 throw new NullPointerException(
750 "There was no DataSourceFactory "
751 + "configured for the connection " + name);
752 }
753 else
754 {
755 throw new TorqueException(e);
756 }
757 }
758 return con;
759 }
760
761 /***
762 * This method returns a Connecton using the given parameters.
763 * You should only use this method if you need user based access to the
764 * database!
765 *
766 * @param name The database name.
767 * @param username The name of the database user.
768 * @param password The password of the database user.
769 * @return A Connection.
770 * @throws TorqueException Any exceptions caught during processing will be
771 * rethrown wrapped into a TorqueException.
772 */
773 public Connection getConnection(String name, String username,
774 String password)
775 throws TorqueException
776 {
777 Connection con = null;
778 DataSourceFactory dsf = null;
779 try
780 {
781 dsf = (DataSourceFactory) dsFactoryMap.get(name);
782 con = dsf.getDataSource().getConnection(username, password);
783 }
784 catch (Exception e)
785 {
786 if (dsf == null && e instanceof NullPointerException)
787 {
788 throw new NullPointerException(
789 "There was no DataSourceFactory "
790 + "configured for the connection " + name);
791 }
792 else
793 {
794 throw new TorqueException(e);
795 }
796 }
797 return con;
798 }
799
800 /***
801 * Returns database adapter for a specific connection pool.
802 *
803 * @param name A pool name.
804 * @return The corresponding database adapter.
805 * @throws TorqueException Any exceptions caught during processing will be
806 * rethrown wrapped into a TorqueException.
807 */
808 public DB getDB(String name) throws TorqueException
809 {
810 return (DB) adapterMap.get(name);
811 }
812
813 ///////////////////////////////////////////////////////////////////////////
814
815 /***
816 * Returns the name of the default database.
817 *
818 * @return name of the default DB
819 */
820 public String getDefaultDB()
821 {
822 if (conf == null)
823 {
824 return DEFAULT_NAME;
825 }
826 else if (defaultDBName == null)
827 {
828 // Determine default database name.
829 defaultDBName =
830 conf.getString(Torque.DATABASE_DEFAULT,
831 DEFAULT_NAME).trim();
832 }
833
834 return defaultDBName;
835 }
836
837 /***
838 * Closes a connection.
839 *
840 * @param con A Connection to close.
841 */
842 public void closeConnection(Connection con)
843 {
844 if (con != null)
845 {
846 try
847 {
848 con.close();
849 }
850 catch (SQLException e)
851 {
852 log.error("Error occured while closing connection.", e);
853 }
854 }
855 }
856 }
This page was automatically generated by Maven