Coverage report

  %line %branch
org.apache.torque.TorqueInstance
64% 
83% 

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

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.