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