KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > torque > TorqueInstance


1 package org.apache.torque;
2
3 /*
4  * Licensed to the Apache Software Foundation (ASF) under one
5  * or more contributor license agreements. See the NOTICE file
6  * distributed with this work for additional information
7  * regarding copyright ownership. The ASF licenses this file
8  * to you under the Apache License, Version 2.0 (the
9  * "License"); you may not use this file except in compliance
10  * with the License. You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17  * KIND, either express or implied. See the License for the
18  * specific language governing permissions and limitations
19  * under the License.
20  */

21
22 import java.sql.Connection JavaDoc;
23 import java.sql.SQLException JavaDoc;
24 import java.util.Collections JavaDoc;
25 import java.util.HashMap JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.Map JavaDoc;
28
29 import org.apache.commons.configuration.Configuration;
30 import org.apache.commons.configuration.ConfigurationException;
31 import org.apache.commons.configuration.PropertiesConfiguration;
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.DataSourceFactory;
37 import org.apache.torque.manager.AbstractBaseManager;
38 import org.apache.torque.map.DatabaseMap;
39 import org.apache.torque.map.MapBuilder;
40 import org.apache.torque.oid.IDBroker;
41 import org.apache.torque.oid.IDGeneratorFactory;
42
43 /**
44  * The core of Torque's implementation. Both the classic {@link
45  * org.apache.torque.Torque} static wrapper and the {@link
46  * org.apache.torque.avalon.TorqueComponent} <a
47  * HREF="http://avalon.apache.org/">Avalon</a> implementation leverage
48  * this class.
49  *
50  * @author <a HREF="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
51  * @author <a HREF="mailto:magnus@handtolvur.is">Magn�s ��r Torfason</a>
52  * @author <a HREF="mailto:jvanzyl@apache.org">Jason van Zyl</a>
53  * @author <a HREF="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
54  * @author <a HREF="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
55  * @author <a HREF="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
56  * @author <a HREF="mailto:kschrader@karmalab.org">Kurt Schrader</a>
57  * @author <a HREF="mailto:tv@apache.org">Thomas Vandahl</a>
58  * @version $Id: TorqueInstance.java 500332 2007-01-26 20:30:34Z tfischer $
59  */

60 public class TorqueInstance
61 {
62     /** Logging */
63     private static Log log = LogFactory.getLog(TorqueInstance.class);
64
65     /** A constant for <code>default</code>. */
66     private static final String JavaDoc DEFAULT_NAME = "default";
67
68     /** The db name that is specified as the default in the property file */
69     private String JavaDoc defaultDBName = null;
70
71     /**
72      * The Map which contains all known databases. All iterations over the map
73      * and other operations where the databaase map needs to stay
74      * in a defined state must be synchronized to this map.
75      */

76     private Map JavaDoc databases = Collections.synchronizedMap(new HashMap JavaDoc());
77
78     /** A repository of Manager instances. */
79     private Map JavaDoc 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      * a flag which indicates whether the DataSourceFactory in the database
89      * named <code>DEFAULT</code> is a reference to another
90      * DataSourceFactory. This is important to know when closing the
91      * DataSourceFactories on shutdown();
92      */

93     private boolean defaultDsfIsReference = false;
94
95     /**
96      * Store mapbuilder classnames for peers that have been referenced prior
97      * to Torque being initialized. This can happen if torque om/peer objects
98      * are serialized then unserialized prior to Torque being reinitialized.
99      * This condition exists in a normal catalina restart.
100      */

101     private Map JavaDoc mapBuilderCache = null;
102
103     /**
104      * Creates a new instance with default configuration.
105      *
106      * @see #resetConfiguration()
107      */

108     public TorqueInstance()
109     {
110         resetConfiguration();
111     }
112
113     /**
114      * Initializes this instance of Torque.
115      *
116      * @see org.apache.stratum.lifecycle.Initializable
117      * @throws TorqueException Any exceptions caught during processing will be
118      * rethrown wrapped into a TorqueException.
119      */

120     private synchronized void initialize() throws TorqueException
121     {
122         log.debug("initialize()");
123
124         if (isInit)
125         {
126             log.debug("Multiple initializations of Torque attempted");
127             return;
128         }
129
130         if (conf == null || conf.isEmpty())
131         {
132             throw new TorqueException("Torque cannot be initialized without "
133                     + "a valid configuration. Please check the log files "
134                     + "for further details.");
135         }
136
137         // Now that we have dealt with processing the log4j properties
138
// that may be contained in the configuration we will make the
139
// configuration consist only of the remain torque specific
140
// properties that are contained in the configuration. First
141
// look for properties that are in the "torque" namespace.
142

143         Configuration subConf = conf.subset(Torque.TORQUE_KEY);
144         if (subConf == null || subConf.isEmpty())
145         {
146             String JavaDoc error = ("Invalid configuration. No keys starting with "
147                     + Torque.TORQUE_KEY
148                     + " found in configuration");
149             log.error(error);
150             throw new TorqueException(error);
151         }
152         setConfiguration(subConf);
153
154         initDefaultDbName(conf);
155         initAdapters(conf);
156         initDataSourceFactories(conf);
157
158         // setup manager mappings
159
initManagerMappings(conf);
160
161         isInit = true;
162
163         // re-build any MapBuilders that may have gone lost during serialization
164
synchronized (mapBuilderCache)
165         {
166             for (Iterator JavaDoc i = mapBuilderCache.entrySet().iterator(); i.hasNext();)
167             {
168                 Map.Entry JavaDoc entry = (Map.Entry JavaDoc)i.next();
169                 
170                 if (null == entry.getValue())
171                 {
172                     try
173                     {
174                         // create and build the MapBuilder
175
MapBuilder builder = (MapBuilder) Class.forName((String JavaDoc) entry.getKey()).newInstance();
176         
177                         if (!builder.isBuilt())
178                         {
179                             builder.doBuild();
180                         }
181     
182                         entry.setValue(builder);
183                     }
184                     catch (Exception JavaDoc e)
185                     {
186                         throw new TorqueException(e);
187                     }
188                 }
189             }
190         }
191     }
192
193
194     /**
195      * Initializes the name of the default database and
196      * associates the database with the name <code>DEFAULT_NAME</code>
197      * to the default database.
198      *
199      * @param conf the configuration representing the torque section.
200      * of the properties file.
201      * @throws TorqueException if the appropriate key is not set.
202      */

203     private void initDefaultDbName(Configuration conf)
204             throws TorqueException
205     {
206         // Determine default database name.
207
defaultDBName =
208                 conf.getString(
209                         Torque.DATABASE_KEY
210                         + "."
211                         + Torque.DEFAULT_KEY);
212         if (defaultDBName == null)
213         {
214             String JavaDoc error = "Invalid configuration: Key "
215                     + Torque.TORQUE_KEY
216                     + "."
217                     + Torque.DATABASE_KEY
218                     + "."
219                     + Torque.DEFAULT_KEY
220                     + " not set";
221             log.error(error);
222             throw new TorqueException(error);
223         }
224     }
225
226     /**
227      * Reads the adapter settings from the configuration and
228      * assigns the appropriate database adapters and Id Generators
229      * to the databases.
230      *
231      * @param conf the Configuration representing the torque section of the
232      * properties file
233      * @throws TorqueException Any exceptions caught during processing will be
234      * rethrown wrapped into a TorqueException.
235      */

236     private void initAdapters(Configuration conf)
237             throws TorqueException
238     {
239         log.debug("initAdapters(" + conf + ")");
240
241         Configuration c = conf.subset(Torque.DATABASE_KEY);
242         if (c == null || c.isEmpty())
243         {
244             String JavaDoc error = "Invalid configuration : "
245                     + "No keys starting with "
246                     + Torque.TORQUE_KEY
247                     + "."
248                     + Torque.DATABASE_KEY
249                     + " found in configuration";
250             log.error(error);
251             throw new TorqueException(error);
252         }
253
254         try
255         {
256             for (Iterator JavaDoc it = c.getKeys(); it.hasNext();)
257             {
258                 String JavaDoc key = (String JavaDoc) it.next();
259                 if (key.endsWith(DB.ADAPTER_KEY)
260                         || key.endsWith(DB.DRIVER_KEY))
261                 {
262                     String JavaDoc adapter = c.getString(key);
263                     String JavaDoc handle = key.substring(0, key.indexOf('.'));
264
265                     DB db;
266
267                     db = DBFactory.create(adapter);
268
269                     // Not supported, try manually defined adapter class
270
if (db == null)
271                     {
272                         String JavaDoc adapterClassName = c.getString(key + "." + adapter + ".className", null);
273                         db = DBFactory.create(adapter, adapterClassName);
274                     }
275
276                     Database database = getOrCreateDatabase(handle);
277
278                     // register the adapter for this name
279
database.setAdapter(db);
280                     log.debug("Adding " + adapter + " -> "
281                             + handle + " as Adapter");
282
283                     // add Id generators
284

285                     // first make sure that the dtabaseMap exists for the name
286
// as the idGenerators are still stored in the database map
287
// TODO: change when the idGenerators are stored in the
288
// database
289
getDatabaseMap(handle);
290                     for (int i = 0;
291                             i < IDGeneratorFactory.ID_GENERATOR_METHODS.length;
292                             i++)
293                     {
294                         database.addIdGenerator(
295                                 IDGeneratorFactory.ID_GENERATOR_METHODS[i],
296                                 IDGeneratorFactory.create(db, handle));
297                     }
298                 }
299             }
300         }
301         catch (InstantiationException JavaDoc e)
302         {
303             log.error("Error creating a database adapter instance", e);
304             throw new TorqueException(e);
305         }
306         catch (TorqueException e)
307         {
308             log.error("Error reading configuration seeking database "
309                       + "adapters", e);
310             throw new TorqueException(e);
311         }
312
313         // check that at least the default database has got an adapter.
314
Database defaultDatabase
315                 = (Database) databases.get(Torque.getDefaultDB());
316         if (defaultDatabase == null
317             || defaultDatabase.getAdapter() == null)
318         {
319             String JavaDoc error = "Invalid configuration : "
320                     + "No adapter definition found for default DB "
321                     + "An adapter must be defined under "
322                     + Torque.TORQUE_KEY
323                     + "."
324                     + Torque.DATABASE_KEY
325                     + "."
326                     + Torque.getDefaultDB()
327                     + "."
328                     + DB.ADAPTER_KEY;
329             log.error(error);
330             throw new TorqueException(error);
331         }
332     }
333
334     /**
335      * Reads the settings for the DataSourceFactories from the configuration
336      * and creates and/or cinfigures the DataSourceFactories for the databases.
337      * If no DataSorceFactory is assigned to the database with the name
338      * <code>DEFAULT_NAME</code>, a reference to the DataSourceFactory
339      * of the default daztabase is made from the database with the name
340      * <code>DEFAULT_NAME</code>.
341      *
342      * @param conf the Configuration representing the properties file
343      * @throws TorqueException Any exceptions caught during processing will be
344      * rethrown wrapped into a TorqueException.
345      */

346     private void initDataSourceFactories(Configuration conf)
347             throws TorqueException
348     {
349         log.debug("initDataSourceFactories(" + conf + ")");
350
351         Configuration c = conf.subset(DataSourceFactory.DSFACTORY_KEY);
352         if (c == null || c.isEmpty())
353         {
354             String JavaDoc error = "Invalid configuration: "
355                     + "No keys starting with "
356                     + Torque.TORQUE_KEY
357                     + "."
358                     + DataSourceFactory.DSFACTORY_KEY
359                     + " found in configuration";
360             log.error(error);
361             throw new TorqueException(error);
362         }
363
364         try
365         {
366             for (Iterator JavaDoc it = c.getKeys(); it.hasNext();)
367             {
368                 String JavaDoc key = (String JavaDoc) it.next();
369                 if (key.endsWith(DataSourceFactory.FACTORY_KEY))
370                 {
371                     String JavaDoc classname = c.getString(key);
372                     String JavaDoc handle = key.substring(0, key.indexOf('.'));
373                     log.debug("handle: " + handle
374                             + " DataSourceFactory: " + classname);
375                     Class JavaDoc dsfClass = Class.forName(classname);
376                     DataSourceFactory dsf =
377                             (DataSourceFactory) dsfClass.newInstance();
378                     dsf.initialize(c.subset(handle));
379
380                     Database database = getOrCreateDatabase(handle);
381                     database.setDataSourceFactory(dsf);
382                 }
383             }
384         }
385         catch (RuntimeException JavaDoc e)
386         {
387             log.error("Runtime Error reading adapter configuration", e);
388             throw new TorqueRuntimeException(e);
389         }
390         catch (Exception JavaDoc e)
391         {
392             log.error("Error reading adapter configuration", e);
393             throw new TorqueException(e);
394         }
395
396         Database defaultDatabase
397                 = (Database) databases.get(defaultDBName);
398         if (defaultDatabase == null
399             || defaultDatabase.getDataSourceFactory() == null)
400         {
401             String JavaDoc error = "Invalid configuration : "
402                     + "No DataSourceFactory definition for default DB found. "
403                     + "A DataSourceFactory must be defined under the key"
404                     + Torque.TORQUE_KEY
405                     + "."
406                     + DataSourceFactory.DSFACTORY_KEY
407                     + "."
408                     + defaultDBName
409                     + "."
410                     + DataSourceFactory.FACTORY_KEY;
411             log.error(error);
412             throw new TorqueException(error);
413         }
414
415         // As there might be a default database configured
416
// to map "default" onto an existing datasource, we
417
// must check, whether there _is_ really an entry for
418
// the "default" in the dsFactoryMap or not. If it is
419
// not, then add a dummy entry for the "default"
420
//
421
// Without this, you can't actually access the "default"
422
// data-source, even if you have an entry like
423
//
424
// database.default = bookstore
425
//
426
// in your Torque.properties
427
//
428

429         {
430             Database databaseInfoForKeyDefault
431                     = getOrCreateDatabase(DEFAULT_NAME);
432             if ((!defaultDBName.equals(DEFAULT_NAME))
433                 && databaseInfoForKeyDefault.getDataSourceFactory() == null)
434             {
435                 log.debug("Adding the DatasourceFactory from database "
436                         + defaultDBName
437                         + " onto database " + DEFAULT_NAME);
438                 databaseInfoForKeyDefault.setDataSourceFactory(
439                         defaultDatabase.getDataSourceFactory());
440                 this.defaultDsfIsReference = true;
441             }
442         }
443
444     }
445
446     /**
447      * Initialization of Torque with a properties file.
448      *
449      * @param configFile The absolute path to the configuration file.
450      * @throws TorqueException Any exceptions caught during processing will be
451      * rethrown wrapped into a TorqueException.
452      */

453     public void init(String JavaDoc configFile)
454             throws TorqueException
455     {
456         log.debug("init(" + configFile + ")");
457         try
458         {
459             Configuration configuration
460                     = new PropertiesConfiguration(configFile);
461
462             log.debug("Config Object is " + configuration);
463             init(configuration);
464         }
465         catch (ConfigurationException e)
466         {
467             throw new TorqueException(e);
468         }
469     }
470
471     /**
472      * Initialization of Torque with a Configuration object.
473      *
474      * @param conf The Torque configuration.
475      * @throws TorqueException Any exceptions caught during processing will be
476      * rethrown wrapped into a TorqueException.
477      */

478     public synchronized void init(Configuration conf)
479             throws TorqueException
480     {
481         log.debug("init(" + conf + ")");
482         setConfiguration(conf);
483         initialize();
484     }
485
486
487     /**
488      * Creates a mapping between classes and their manager classes.
489      *
490      * The mapping is built according to settings present in
491      * properties file. The entries should have the
492      * following form:
493      *
494      * <pre>
495      * torque.managed_class.com.mycompany.Myclass.manager= \
496      * com.mycompany.MyManagerImpl
497      * services.managed_class.com.mycompany.Myotherclass.manager= \
498      * com.mycompany.MyOtherManagerImpl
499      * </pre>
500      *
501      * <br>
502      *
503      * Generic ServiceBroker provides no Services.
504      *
505      * @param conf the Configuration representing the properties file
506      * @throws TorqueException Any exceptions caught during processing will be
507      * rethrown wrapped into a TorqueException.
508      */

509     protected void initManagerMappings(Configuration conf)
510             throws TorqueException
511     {
512         int pref = Torque.MANAGER_PREFIX.length();
513         int suff = Torque.MANAGER_SUFFIX.length();
514
515         for (Iterator JavaDoc it = conf.getKeys(); it.hasNext();)
516         {
517             String JavaDoc key = (String JavaDoc) it.next();
518
519             if (key.startsWith(Torque.MANAGER_PREFIX)
520                     && key.endsWith(Torque.MANAGER_SUFFIX))
521             {
522                 String JavaDoc managedClassKey = key.substring(pref,
523                         key.length() - suff);
524                 if (!managers.containsKey(managedClassKey))
525                 {
526                     String JavaDoc managerClass = conf.getString(key);
527                     log.info("Added Manager for Class: " + managedClassKey
528                             + " -> " + managerClass);
529                     try
530                     {
531                         initManager(managedClassKey, managerClass);
532                     }
533                     catch (TorqueException e)
534                     {
535                         // the exception thrown here seems to disappear.
536
// At least when initialized by Turbine, should find
537
// out why, but for now make sure it is noticed.
538
log.error("", e);
539                         e.printStackTrace();
540                         throw e;
541                     }
542                 }
543             }
544         }
545     }
546
547     /**
548      * Initialize a manager
549      *
550      * @param name name of the manager
551      * @param className name of the manager class
552      * @throws TorqueException Any exceptions caught during processing will be
553      * rethrown wrapped into a TorqueException.
554      */

555     private synchronized void initManager(String JavaDoc name, String JavaDoc className)
556             throws TorqueException
557     {
558         AbstractBaseManager manager = (AbstractBaseManager) managers.get(name);
559
560         if (manager == null)
561         {
562             if (className != null && className.length() != 0)
563             {
564                 try
565                 {
566                     manager = (AbstractBaseManager)
567                             Class.forName(className).newInstance();
568                     managers.put(name, manager);
569                 }
570                 catch (Exception JavaDoc e)
571                 {
572                     throw new TorqueException("Could not instantiate "
573                             + "manager associated with class: "
574                             + name, e);
575                 }
576             }
577         }
578     }
579
580     /**
581      * Determine whether Torque has already been initialized.
582      *
583      * @return true if Torque is already initialized
584      */

585     public boolean isInit()
586     {
587         return isInit;
588     }
589
590     /**
591      * Sets the configuration for Torque and all dependencies.
592      * The prefix <code>TORQUE_KEY</code> needs to be removed from the
593      * configuration keys for the provided configuration.
594      *
595      * @param conf the Configuration.
596      */

597     public void setConfiguration(Configuration conf)
598     {
599         log.debug("setConfiguration(" + conf + ")");
600         this.conf = conf;
601     }
602
603     /**
604      * Get the configuration for this component.
605      *
606      * @return the Configuration
607      */

608     public Configuration getConfiguration()
609     {
610         log.debug("getConfiguration() = " + conf);
611         return conf;
612     }
613
614     /**
615      * This method returns a Manager for the given name.
616      *
617      * @param name name of the manager
618      * @return a Manager
619      */

620     public AbstractBaseManager getManager(String JavaDoc name)
621     {
622         AbstractBaseManager m = (AbstractBaseManager) managers.get(name);
623         if (m == null)
624         {
625             log.error("No configured manager for key " + name + ".");
626         }
627         return m;
628     }
629
630     /**
631      * This methods returns either the Manager from the configuration file,
632      * or the default one provided by the generated code.
633      *
634      * @param name name of the manager
635      * @param defaultClassName the class to use if name has not been configured
636      * @return a Manager
637      */

638     public AbstractBaseManager getManager(String JavaDoc name,
639             String JavaDoc defaultClassName)
640     {
641         AbstractBaseManager m = (AbstractBaseManager) managers.get(name);
642         if (m == null)
643         {
644             log.debug("Added late Manager mapping for Class: "
645                     + name + " -> " + defaultClassName);
646
647             try
648             {
649                 initManager(name, defaultClassName);
650             }
651             catch (TorqueException e)
652             {
653                 log.error(e.getMessage(), e);
654             }
655
656             // Try again now that the default manager should be in the map
657
m = (AbstractBaseManager) managers.get(name);
658         }
659
660         return m;
661     }
662
663     /**
664      * Shuts down the service.
665      *
666      * This method halts the IDBroker's daemon thread in all of
667      * the DatabaseMap's. It also closes all SharedPoolDataSourceFactories
668      * and PerUserPoolDataSourceFactories initialized by Torque.
669      * @exception TorqueException if a DataSourceFactory could not be closed
670      * cleanly. Only the first exception is rethrown, any following
671      * exceptions are logged but ignored.
672      */

673     public synchronized void shutdown()
674         throws TorqueException
675     {
676         // stop the idbrokers
677
synchronized (databases)
678         {
679             for (Iterator JavaDoc it = databases.values().iterator(); it.hasNext();)
680             {
681                 Database database = (Database) it.next();
682                 IDBroker idBroker = database.getIDBroker();
683                 if (idBroker != null)
684                 {
685                     idBroker.stop();
686                 }
687             }
688         }
689
690         // shut down the data source factories
691
TorqueException exception = null;
692         synchronized (databases)
693         {
694             for (Iterator JavaDoc it = databases.keySet().iterator(); it.hasNext();)
695             {
696                 Object JavaDoc databaseKey = it.next();
697
698                 Database database
699                         = (Database) databases.get(databaseKey);
700                 if (DEFAULT_NAME.equals(databaseKey) && defaultDsfIsReference)
701                 {
702                     // the DataSourceFactory of the database with the name
703
// DEFAULT_NAME is just a reference to aynother entry.
704
// Do not close because this leads to closing
705
// the same DataSourceFactory twice.
706
database.setDataSourceFactory(null);
707                     break;
708                 }
709
710                 try
711                 {
712                     DataSourceFactory dataSourceFactory
713                             = database.getDataSourceFactory();
714                     if (dataSourceFactory != null)
715                     {
716                         dataSourceFactory.close();
717                         database.setDataSourceFactory(null);
718                     }
719                 }
720                 catch (TorqueException e)
721                 {
722                     log.error("Error while closing the DataSourceFactory "
723                             + databaseKey,
724                             e);
725                     if (exception == null)
726                     {
727                         exception = e;
728                     }
729                 }
730             }
731         }
732         if (exception != null)
733         {
734             throw exception;
735         }
736         resetConfiguration();
737     }
738
739     /**
740      * Resets some internal configuration variables to
741      * their defaults.
742      */

743     private void resetConfiguration()
744     {
745         mapBuilderCache = Collections.synchronizedMap(new HashMap JavaDoc());
746         managers = new HashMap JavaDoc();
747         isInit = false;
748     }
749
750     /**
751      * Returns the default database map information.
752      *
753      * @return A DatabaseMap.
754      * @throws TorqueException Any exceptions caught during processing will be
755      * rethrown wrapped into a TorqueException.
756      */

757     public DatabaseMap getDatabaseMap()
758             throws TorqueException
759     {
760         return getDatabaseMap(getDefaultDB());
761     }
762
763     /**
764      * Returns the database map information. Name relates to the name
765      * of the connection pool to associate with the map.
766      *
767      * @param name The name of the database corresponding to the
768      * <code>DatabaseMap</code> to retrieve.
769      * @return The named <code>DatabaseMap</code>.
770      * @throws TorqueException Any exceptions caught during processing will be
771      * rethrown wrapped into a TorqueException.
772      */

773     public DatabaseMap getDatabaseMap(String JavaDoc name)
774             throws TorqueException
775     {
776         if (name == null)
777         {
778             throw new TorqueException ("DatabaseMap name was null!");
779         }
780
781         Database database = getOrCreateDatabase(name);
782         return database.getDatabaseMap();
783     }
784
785     /**
786      * Get the registered MapBuilders
787      *
788      * @return the MapBuilder cache
789      *
790      */

791     public Map JavaDoc getMapBuilders()
792     {
793         return mapBuilderCache;
794     }
795
796     /**
797      * Register a MapBuilder
798      *
799      * @param className the MapBuilder
800      */

801     public void registerMapBuilder(String JavaDoc className)
802     {
803         mapBuilderCache.put(className, null);
804     }
805
806     /**
807      * Register a MapBuilder
808      *
809      * @param builder the instance of the MapBuilder
810      *
811      */

812     public void registerMapBuilder(MapBuilder builder)
813     {
814         mapBuilderCache.put(builder.getClass().getName(), builder);
815     }
816     
817     /**
818      * Get a MapBuilder
819      *
820      * @param className of the MapBuilder
821      * @return A MapBuilder, not null
822      * @throws TorqueException if the Map Builder cannot be instantiated
823      *
824      */

825     public MapBuilder getMapBuilder(String JavaDoc className)
826         throws TorqueException
827     {
828         try
829         {
830             MapBuilder mb = (MapBuilder)mapBuilderCache.get(className);
831
832             if (mb == null)
833             {
834                 mb = (MapBuilder) Class.forName(className).newInstance();
835                 // Cache the MapBuilder before it is built.
836
mapBuilderCache.put(className, mb);
837             }
838
839             if (mb.isBuilt())
840             {
841                 return mb;
842             }
843
844             try
845             {
846                 mb.doBuild();
847             }
848             catch (Exception JavaDoc e)
849             {
850                 // remove the MapBuilder from the cache if it can't be built correctly
851
mapBuilderCache.remove(className);
852                 throw e;
853             }
854
855             return mb;
856         }
857         catch (Exception JavaDoc e)
858         {
859             log.error("getMapBuilder failed trying to instantiate: "
860                     + className, e);
861             throw new TorqueException(e);
862         }
863     }
864     
865     /**
866      * This method returns a Connection from the default pool.
867      *
868      * @return The requested connection, never null.
869      * @throws TorqueException Any exceptions caught during processing will be
870      * rethrown wrapped into a TorqueException.
871      */

872     public Connection JavaDoc getConnection()
873             throws TorqueException
874     {
875         return getConnection(getDefaultDB());
876     }
877
878     /**
879      * Returns a database connection to the database with the key
880      * <code>name</code>.
881      * @param name The database name.
882      * @return a database connection, never null.
883      * @throws TorqueException If no DataSourceFactory is configured for the
884      * named database, the connection information is wrong, or the
885      * connection cannot be returned for any other reason.
886      */

887     public Connection JavaDoc getConnection(String JavaDoc name)
888             throws TorqueException
889     {
890         if (!Torque.isInit())
891         {
892             throw new TorqueException("Torque is not initialized");
893         }
894         try
895         {
896             return getDatabase(name)
897                     .getDataSourceFactory()
898                     .getDataSource()
899                     .getConnection();
900         }
901         catch (SQLException JavaDoc se)
902         {
903             throw new TorqueException(se);
904         }
905     }
906
907     /**
908      * Returns the DataSourceFactory for the database with the name
909      * <code>name</code>.
910      *
911      * @param name The name of the database to get the DSF for.
912      * @return A DataSourceFactory object, never null.
913      * @throws TorqueException if Torque is not initiliaized, or
914      * no DatasourceFactory is configured for the given name.
915      */

916     public DataSourceFactory getDataSourceFactory(String JavaDoc name)
917             throws TorqueException
918     {
919         Database database = getDatabase(name);
920
921         DataSourceFactory dsf = null;
922         if (database != null)
923         {
924             dsf = database.getDataSourceFactory();
925         }
926
927         if (dsf == null)
928         {
929             throw new TorqueException(
930                     "There was no DataSourceFactory "
931                     + "configured for the connection " + name);
932         }
933
934         return dsf;
935     }
936
937     /**
938      * This method returns a Connection using the given parameters.
939      * You should only use this method if you need user based access to the
940      * database!
941      *
942      * @param name The database name.
943      * @param username The name of the database user.
944      * @param password The password of the database user.
945      * @return A Connection.
946      * @throws TorqueException Any exceptions caught during processing will be
947      * rethrown wrapped into a TorqueException.
948      */

949     public Connection JavaDoc getConnection(String JavaDoc name, String JavaDoc username,
950             String JavaDoc password)
951             throws TorqueException
952     {
953         if (!Torque.isInit())
954         {
955             throw new TorqueException("Torque is not initialized");
956         }
957         try
958         {
959             return getDataSourceFactory(name)
960                     .getDataSource().getConnection(username, password);
961         }
962         catch (SQLException JavaDoc se)
963         {
964             throw new TorqueException(se);
965         }
966     }
967
968     /**
969      * Returns the database adapter for a specific database.
970      *
971      * @param name the name of the database to get the adapter for.
972      * @return The corresponding database adapter, or null if no database
973      * adapter is defined for the given database.
974      * @throws TorqueException Any exceptions caught during processing will be
975      * rethrown wrapped into a TorqueException.
976      */

977     public DB getDB(String JavaDoc name) throws TorqueException
978     {
979         Database database = getDatabase(name);
980         if (database == null)
981         {
982             return null;
983         }
984         return database.getAdapter();
985     }
986
987     ///////////////////////////////////////////////////////////////////////////
988

989     /**
990      * Returns the name of the default database.
991      *
992      * @return name of the default DB, or null if Torque is not initialized yet
993      */

994     public String JavaDoc getDefaultDB()
995     {
996         return defaultDBName;
997     }
998
999     /**
1000     * Closes a connection.
1001     *
1002     * @param con A Connection to close.
1003     */

1004    public void closeConnection(Connection JavaDoc con)
1005    {
1006        if (con != null)
1007        {
1008            try
1009            {
1010                con.close();
1011            }
1012            catch (SQLException JavaDoc e)
1013            {
1014                log.error("Error occured while closing connection.", e);
1015            }
1016        }
1017    }
1018
1019    /**
1020     * Sets the current schema for a database connection
1021     *
1022     * @param name The database name.
1023     * @param schema The current schema name.
1024     * @throws TorqueException Any exceptions caught during processing will be
1025     * rethrown wrapped into a TorqueException.
1026     */

1027    public void setSchema(String JavaDoc name, String JavaDoc schema)
1028            throws TorqueException
1029    {
1030        getOrCreateDatabase(name).setSchema(schema);
1031    }
1032
1033    /**
1034     * This method returns the current schema for a database connection
1035     *
1036     * @param name The database name.
1037     * @return The current schema name. Null means, no schema has been set.
1038     * @throws TorqueException Any exceptions caught during processing will be
1039     * rethrown wrapped into a TorqueException.
1040     */

1041    public String JavaDoc getSchema(String JavaDoc name)
1042        throws TorqueException
1043    {
1044        Database database = getDatabase(name);
1045        if (database == null)
1046        {
1047            return null;
1048        }
1049        return database.getSchema();
1050    }
1051
1052    /**
1053     * Returns the database for the key <code>databaseName</code>.
1054     *
1055     * @param databaseName the key to get the database for.
1056     * @return the database for the specified key, or null if the database
1057     * does not exist.
1058     * @throws TorqueException if Torque is not yet initialized.
1059     */

1060    public Database getDatabase(String JavaDoc databaseName) throws TorqueException
1061    {
1062        if (!isInit())
1063        {
1064            throw new TorqueException("Torque is not initialized.");
1065        }
1066        return (Database) databases.get(databaseName);
1067    }
1068
1069    /**
1070     * Returns a Map containing all Databases registered to Torque.
1071     * The key of the Map is the name of the database, and the value is the
1072     * database instance. <br/>
1073     * Note that in the very special case where a new database which
1074     * is not configured in Torque's configuration gets known to Torque
1075     * at a later time, the returned map may change, and there is no way to
1076     * protect you against this.
1077     *
1078     * @return a Map containing all Databases known to Torque, never null.
1079     * @throws TorqueException if Torque is not yet initialized.
1080     */

1081    public Map JavaDoc getDatabases() throws TorqueException
1082    {
1083        if (!isInit())
1084        {
1085            throw new TorqueException("Torque is not initialized.");
1086        }
1087        return Collections.unmodifiableMap(databases);
1088    }
1089
1090    /**
1091     * Returns the database for the key <code>databaseName</code>.
1092     * If no database is associated to the specified key,
1093     * a new database is created, mapped to the specified key, and returned.
1094     *
1095     * @param databaseName the key to get the database for.
1096     * @return the database associated with specified key, or the newly created
1097     * database, never null.
1098     */

1099    public Database getOrCreateDatabase(String JavaDoc databaseName)
1100    {
1101        synchronized (databases)
1102        {
1103            Database result = (Database) databases.get(databaseName);
1104            if (result == null)
1105            {
1106                result = new Database(databaseName);
1107                databases.put(databaseName, result);
1108            }
1109            return result;
1110        }
1111    }
1112}
1113
Popular Tags