View Javadoc

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