Coverage report

  %line %branch
org.apache.torque.TorqueInstance
61% 
75% 

 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.Collections;
 25  
 import java.util.HashMap;
 26  
 import java.util.Iterator;
 27  
 import java.util.Map;
 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 571790 2007-09-01 12:40:44Z tv $
 59  
  */
 60  
 public class TorqueInstance
 61  
 {
 62  
     /** Logging */
 63  60
     private static Log log = LogFactory.getLog(TorqueInstance.class);
 64  
 
 65  
     /** A constant for <code>default</code>. */
 66  
     private static final String DEFAULT_NAME = "default";
 67  
 
 68  
     /** The db name that is specified as the default in the property file */
 69  36
     private String 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  36
     private Map databases = Collections.synchronizedMap(new HashMap());
 77  
 
 78  
     /** A repository of Manager instances. */
 79  
     private Map managers;
 80  
 
 81  
     /** Torque-specific configuration. */
 82  
     private Configuration conf;
 83  
 
 84  
     /** flag to set to true once this class has been initialized */
 85  36
     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  36
     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  36
     private Map mapBuilderCache = null;
 102  
 
 103  
     /**
 104  
      * Creates a new instance with default configuration.
 105  
      *
 106  
      * @see #resetConfiguration()
 107  
      */
 108  
     public TorqueInstance()
 109  36
     {
 110  36
         resetConfiguration();
 111  36
     }
 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  30
         log.debug("initialize()");
 123  
 
 124  30
         if (isInit)
 125  
         {
 126  0
             log.debug("Multiple initializations of Torque attempted");
 127  0
             return;
 128  
         }
 129  
 
 130  30
         if (conf == null || conf.isEmpty())
 131  
         {
 132  0
             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  30
         Configuration subConf = conf.subset(Torque.TORQUE_KEY);
 144  30
         if (subConf == null || subConf.isEmpty())
 145  
         {
 146  0
             String error = ("Invalid configuration. No keys starting with "
 147  
                     + Torque.TORQUE_KEY
 148  
                     + " found in configuration");
 149  0
             log.error(error);
 150  0
             throw new TorqueException(error);
 151  
         }
 152  30
         setConfiguration(subConf);
 153  
 
 154  30
         initDefaultDbName(conf);
 155  30
         initAdapters(conf);
 156  30
         initDataSourceFactories(conf);
 157  
 
 158  
         // setup manager mappings
 159  30
         initManagerMappings(conf);
 160  
 
 161  30
         isInit = true;
 162  
 
 163  
         // re-build any MapBuilders that may have gone lost during serialization 
 164  30
         synchronized (mapBuilderCache)
 165  
         {
 166  30
             for (Iterator i = mapBuilderCache.entrySet().iterator(); i.hasNext();)
 167  
             {
 168  6
                 Map.Entry entry = (Map.Entry)i.next();
 169  
                 
 170  6
                 if (null == entry.getValue())
 171  
                 {
 172  
                     try
 173  
                     {
 174  
                         // create and build the MapBuilder
 175  6
                         MapBuilder builder = (MapBuilder) Class.forName((String) entry.getKey()).newInstance();
 176  
         
 177  6
                         if (!builder.isBuilt())
 178  
                         {
 179  6
                             builder.doBuild();
 180  
                         }
 181  
     
 182  6
                         entry.setValue(builder);
 183  
                     }
 184  0
                     catch (Exception e)
 185  
                     {
 186  0
                         throw new TorqueException(e);
 187  9
                     }
 188  
                 }
 189  3
             }
 190  30
         }
 191  30
     }
 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  30
         defaultDBName =
 208  
                 conf.getString(
 209  
                         Torque.DATABASE_KEY
 210  
                         + "."
 211  
                         + Torque.DEFAULT_KEY);
 212  30
         if (defaultDBName == null)
 213  
         {
 214  0
             String error = "Invalid configuration: Key "
 215  
                     + Torque.TORQUE_KEY
 216  
                     + "."
 217  
                     + Torque.DATABASE_KEY
 218  
                     + "."
 219  
                     + Torque.DEFAULT_KEY
 220  
                     + " not set";
 221  0
             log.error(error);
 222  0
             throw new TorqueException(error);
 223  
         }
 224  30
     }
 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  30
         log.debug("initAdapters(" + conf + ")");
 240  
 
 241  30
         Configuration c = conf.subset(Torque.DATABASE_KEY);
 242  30
         if (c == null || c.isEmpty())
 243  
         {
 244  0
             String error = "Invalid configuration : "
 245  
                     + "No keys starting with "
 246  
                     + Torque.TORQUE_KEY
 247  
                     + "."
 248  
                     + Torque.DATABASE_KEY
 249  
                     + " found in configuration";
 250  0
             log.error(error);
 251  0
             throw new TorqueException(error);
 252  
         }
 253  
 
 254  
         try
 255  
         {
 256  30
             for (Iterator it = c.getKeys(); it.hasNext();)
 257  
             {
 258  90
                 String key = (String) it.next();
 259  90
                 if (key.endsWith(DB.ADAPTER_KEY)
 260  
                         || key.endsWith(DB.DRIVER_KEY))
 261  
                 {
 262  30
                     String adapter = c.getString(key);
 263  30
                     String handle = key.substring(0, key.indexOf('.'));
 264  
 
 265  
                     DB db;
 266  
 
 267  30
                     db = DBFactory.create(adapter);
 268  
 
 269  
                     // Not supported, try manually defined adapter class
 270  30
                     if (db == null)
 271  
                     {
 272  30
                         String adapterClassName = c.getString(key + "." + adapter + ".className", null);
 273  30
                         db = DBFactory.create(adapter, adapterClassName);
 274  
                     }
 275  
 
 276  30
                     Database database = getOrCreateDatabase(handle);
 277  
 
 278  
                     // register the adapter for this name
 279  30
                     database.setAdapter(db);
 280  30
                     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  30
                     getDatabaseMap(handle);
 290  30
                     for (int i = 0;
 291  120
                             i < IDGeneratorFactory.ID_GENERATOR_METHODS.length;
 292  90
                             i++)
 293  
                     {
 294  90
                         database.addIdGenerator(
 295  
                                 IDGeneratorFactory.ID_GENERATOR_METHODS[i],
 296  
                                 IDGeneratorFactory.create(db, handle));
 297  
                     }
 298  
                 }
 299  45
             }
 300  
         }
 301  0
         catch (InstantiationException e)
 302  
         {
 303  0
             log.error("Error creating a database adapter instance", e);
 304  0
             throw new TorqueException(e);
 305  
         }
 306  0
         catch (TorqueException e)
 307  
         {
 308  0
             log.error("Error reading configuration seeking database "
 309  
                       + "adapters", e);
 310  0
             throw new TorqueException(e);
 311  30
         }
 312  
 
 313  
         // check that at least the default database has got an adapter.
 314  30
         Database defaultDatabase
 315  
                 = (Database) databases.get(Torque.getDefaultDB());
 316  30
         if (defaultDatabase == null
 317  
             || defaultDatabase.getAdapter() == null)
 318  
         {
 319  0
             String 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  0
             log.error(error);
 330  0
             throw new TorqueException(error);
 331  
         }
 332  30
     }
 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  30
         log.debug("initDataSourceFactories(" + conf + ")");
 350  
 
 351  30
         Configuration c = conf.subset(DataSourceFactory.DSFACTORY_KEY);
 352  30
         if (c == null || c.isEmpty())
 353  
         {
 354  0
             String error = "Invalid configuration: "
 355  
                     + "No keys starting with "
 356  
                     + Torque.TORQUE_KEY
 357  
                     + "."
 358  
                     + DataSourceFactory.DSFACTORY_KEY
 359  
                     + " found in configuration";
 360  0
             log.error(error);
 361  0
             throw new TorqueException(error);
 362  
         }
 363  
 
 364  
         try
 365  
         {
 366  30
             for (Iterator it = c.getKeys(); it.hasNext();)
 367  
             {
 368  30
                 String key = (String) it.next();
 369  30
                 if (key.endsWith(DataSourceFactory.FACTORY_KEY))
 370  
                 {
 371  30
                     String classname = c.getString(key);
 372  30
                     String handle = key.substring(0, key.indexOf('.'));
 373  30
                     log.debug("handle: " + handle
 374  
                             + " DataSourceFactory: " + classname);
 375  30
                     Class dsfClass = Class.forName(classname);
 376  30
                     DataSourceFactory dsf =
 377  
                             (DataSourceFactory) dsfClass.newInstance();
 378  30
                     dsf.initialize(c.subset(handle));
 379  
 
 380  30
                     Database database = getOrCreateDatabase(handle);
 381  30
                     database.setDataSourceFactory(dsf);
 382  
                 }
 383  15
             }
 384  
         }
 385  0
         catch (RuntimeException e)
 386  
         {
 387  0
             log.error("Runtime Error reading adapter configuration", e);
 388  0
             throw new TorqueRuntimeException(e);
 389  
         }
 390  0
         catch (Exception e)
 391  
         {
 392  0
             log.error("Error reading adapter configuration", e);
 393  0
             throw new TorqueException(e);
 394  30
         }
 395  
 
 396  30
         Database defaultDatabase
 397  
                 = (Database) databases.get(defaultDBName);
 398  30
         if (defaultDatabase == null
 399  
             || defaultDatabase.getDataSourceFactory() == null)
 400  
         {
 401  0
             String 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  0
             log.error(error);
 412  0
             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  30
             Database databaseInfoForKeyDefault
 431  
                     = getOrCreateDatabase(DEFAULT_NAME);
 432  30
             if ((!defaultDBName.equals(DEFAULT_NAME))
 433  
                 && databaseInfoForKeyDefault.getDataSourceFactory() == null)
 434  
             {
 435  30
                 log.debug("Adding the DatasourceFactory and DatabaseAdapter from database "
 436  
                         + defaultDBName
 437  
                         + " onto database " + DEFAULT_NAME);
 438  30
                 databaseInfoForKeyDefault.setDataSourceFactory(
 439  
                         defaultDatabase.getDataSourceFactory());
 440  30
                 databaseInfoForKeyDefault.setAdapter(
 441  
                         defaultDatabase.getAdapter());
 442  
                 
 443  30
                 this.defaultDsfIsReference = true;
 444  
             }
 445  
         }
 446  
 
 447  30
     }
 448  
 
 449  
     /**
 450  
      * Initialization of Torque with a properties file.
 451  
      *
 452  
      * @param configFile The absolute path to the configuration file.
 453  
      * @throws TorqueException Any exceptions caught during processing will be
 454  
      *         rethrown wrapped into a TorqueException.
 455  
      */
 456  
     public void init(String configFile)
 457  
             throws TorqueException
 458  
     {
 459  24
         log.debug("init(" + configFile + ")");
 460  
         try
 461  
         {
 462  24
             Configuration configuration
 463  
                     = new PropertiesConfiguration(configFile);
 464  
 
 465  24
             log.debug("Config Object is " + configuration);
 466  24
             init(configuration);
 467  
         }
 468  0
         catch (ConfigurationException e)
 469  
         {
 470  0
             throw new TorqueException(e);
 471  24
         }
 472  24
     }
 473  
 
 474  
     /**
 475  
      * Initialization of Torque with a Configuration object.
 476  
      *
 477  
      * @param conf The Torque configuration.
 478  
      * @throws TorqueException Any exceptions caught during processing will be
 479  
      *         rethrown wrapped into a TorqueException.
 480  
      */
 481  
     public synchronized void init(Configuration conf)
 482  
             throws TorqueException
 483  
     {
 484  30
         log.debug("init(" + conf + ")");
 485  30
         setConfiguration(conf);
 486  30
         initialize();
 487  30
     }
 488  
 
 489  
 
 490  
     /**
 491  
      * Creates a mapping between classes and their manager classes.
 492  
      *
 493  
      * The mapping is built according to settings present in
 494  
      * properties file.  The entries should have the
 495  
      * following form:
 496  
      *
 497  
      * <pre>
 498  
      * torque.managed_class.com.mycompany.Myclass.manager= \
 499  
      *          com.mycompany.MyManagerImpl
 500  
      * services.managed_class.com.mycompany.Myotherclass.manager= \
 501  
      *          com.mycompany.MyOtherManagerImpl
 502  
      * </pre>
 503  
      *
 504  
      * <br>
 505  
      *
 506  
      * Generic ServiceBroker provides no Services.
 507  
      *
 508  
      * @param conf the Configuration representing the properties file
 509  
      * @throws TorqueException Any exceptions caught during processing will be
 510  
      *         rethrown wrapped into a TorqueException.
 511  
      */
 512  
     protected void initManagerMappings(Configuration conf)
 513  
             throws TorqueException
 514  
     {
 515  30
         int pref = Torque.MANAGER_PREFIX.length();
 516  30
         int suff = Torque.MANAGER_SUFFIX.length();
 517  
 
 518  30
         for (Iterator it = conf.getKeys(); it.hasNext();)
 519  
         {
 520  150
             String key = (String) it.next();
 521  
 
 522  150
             if (key.startsWith(Torque.MANAGER_PREFIX)
 523  
                     && key.endsWith(Torque.MANAGER_SUFFIX))
 524  
             {
 525  0
                 String managedClassKey = key.substring(pref,
 526  
                         key.length() - suff);
 527  0
                 if (!managers.containsKey(managedClassKey))
 528  
                 {
 529  0
                     String managerClass = conf.getString(key);
 530  0
                     log.info("Added Manager for Class: " + managedClassKey
 531  
                             + " -> " + managerClass);
 532  
                     try
 533  
                     {
 534  0
                         initManager(managedClassKey, managerClass);
 535  
                     }
 536  0
                     catch (TorqueException e)
 537  
                     {
 538  
                         // the exception thrown here seems to disappear.
 539  
                         // At least when initialized by Turbine, should find
 540  
                         // out why, but for now make sure it is noticed.
 541  0
                         log.error("", e);
 542  0
                         e.printStackTrace();
 543  0
                         throw e;
 544  75
                     }
 545  
                 }
 546  
             }
 547  75
         }
 548  30
     }
 549  
 
 550  
     /**
 551  
      * Initialize a manager
 552  
      *
 553  
      * @param name name of the manager
 554  
      * @param className name of the manager class
 555  
      * @throws TorqueException Any exceptions caught during processing will be
 556  
      *         rethrown wrapped into a TorqueException.
 557  
      */
 558  
     private synchronized void initManager(String name, String className)
 559  
             throws TorqueException
 560  
     {
 561  0
         AbstractBaseManager manager = (AbstractBaseManager) managers.get(name);
 562  
 
 563  0
         if (manager == null)
 564  
         {
 565  0
             if (className != null && className.length() != 0)
 566  
             {
 567  
                 try
 568  
                 {
 569  0
                     manager = (AbstractBaseManager)
 570  
                             Class.forName(className).newInstance();
 571  0
                     managers.put(name, manager);
 572  
                 }
 573  0
                 catch (Exception e)
 574  
                 {
 575  0
                     throw new TorqueException("Could not instantiate "
 576  
                             + "manager associated with class: "
 577  
                             + name, e);
 578  0
                 }
 579  
             }
 580  
         }
 581  0
     }
 582  
 
 583  
     /**
 584  
      * Determine whether Torque has already been initialized.
 585  
      *
 586  
      * @return true if Torque is already initialized
 587  
      */
 588  
     public boolean isInit()
 589  
     {
 590  522
         return isInit;
 591  
     }
 592  
 
 593  
     /**
 594  
      * Sets the configuration for Torque and all dependencies.
 595  
      * The prefix <code>TORQUE_KEY</code> needs to be removed from the
 596  
      * configuration keys for the provided configuration.
 597  
      *
 598  
      * @param conf the Configuration.
 599  
      */
 600  
     public void setConfiguration(Configuration conf)
 601  
     {
 602  60
         log.debug("setConfiguration(" + conf + ")");
 603  60
         this.conf = conf;
 604  60
     }
 605  
 
 606  
     /**
 607  
      * Get the configuration for this component.
 608  
      *
 609  
      * @return the Configuration
 610  
      */
 611  
     public Configuration getConfiguration()
 612  
     {
 613  90
         log.debug("getConfiguration() = " + conf);
 614  90
         return conf;
 615  
     }
 616  
 
 617  
     /**
 618  
      * This method returns a Manager for the given name.
 619  
      *
 620  
      * @param name name of the manager
 621  
      * @return a Manager
 622  
      */
 623  
     public AbstractBaseManager getManager(String name)
 624  
     {
 625  0
         AbstractBaseManager m = (AbstractBaseManager) managers.get(name);
 626  0
         if (m == null)
 627  
         {
 628  0
             log.error("No configured manager for key " + name + ".");
 629  
         }
 630  0
         return m;
 631  
     }
 632  
 
 633  
     /**
 634  
      * This methods returns either the Manager from the configuration file,
 635  
      * or the default one provided by the generated code.
 636  
      *
 637  
      * @param name name of the manager
 638  
      * @param defaultClassName the class to use if name has not been configured
 639  
      * @return a Manager
 640  
      */
 641  
     public AbstractBaseManager getManager(String name,
 642  
             String defaultClassName)
 643  
     {
 644  0
         AbstractBaseManager m = (AbstractBaseManager) managers.get(name);
 645  0
         if (m == null)
 646  
         {
 647  0
             log.debug("Added late Manager mapping for Class: "
 648  
                     + name + " -> " + defaultClassName);
 649  
 
 650  
             try
 651  
             {
 652  0
                 initManager(name, defaultClassName);
 653  
             }
 654  0
             catch (TorqueException e)
 655  
             {
 656  0
                 log.error(e.getMessage(), e);
 657  0
             }
 658  
 
 659  
             // Try again now that the default manager should be in the map
 660  0
             m = (AbstractBaseManager) managers.get(name);
 661  
         }
 662  
 
 663  0
         return m;
 664  
     }
 665  
 
 666  
     /**
 667  
      * Shuts down the service.
 668  
      *
 669  
      * This method halts the IDBroker's daemon thread in all of
 670  
      * the DatabaseMap's. It also closes all SharedPoolDataSourceFactories
 671  
      * and PerUserPoolDataSourceFactories initialized by Torque.
 672  
      * @exception TorqueException if a DataSourceFactory could not be closed
 673  
      *            cleanly. Only the first exception is rethrown, any following
 674  
      *            exceptions are logged but ignored.
 675  
      */
 676  
     public synchronized void shutdown()
 677  
         throws TorqueException
 678  
     {
 679  
         // stop the idbrokers
 680  12
         synchronized (databases)
 681  
         {
 682  12
             for (Iterator it = databases.values().iterator(); it.hasNext();)
 683  
             {
 684  24
                 Database database = (Database) it.next();
 685  24
                 IDBroker idBroker = database.getIDBroker();
 686  24
                 if (idBroker != null)
 687  
                 {
 688  0
                     idBroker.stop();
 689  
                 }
 690  12
             }
 691  12
         }
 692  
         
 693  
         // shut down the cache managers
 694  12
         synchronized (managers)
 695  
         {
 696  12
             for (Iterator it = managers.entrySet().iterator(); it.hasNext();)
 697  
             {
 698  0
                 Map.Entry mentry = (Map.Entry)it.next();
 699  
                 
 700  0
                 AbstractBaseManager manager = (AbstractBaseManager)mentry.getValue();
 701  0
                 manager.dispose();
 702  0
                 it.remove();
 703  
             }
 704  12
         }
 705  
 
 706  
         // shut down the data source factories
 707  12
         TorqueException exception = null;
 708  12
         synchronized (databases)
 709  
         {
 710  12
             for (Iterator it = databases.keySet().iterator(); it.hasNext();)
 711  
             {
 712  24
                 Object databaseKey = it.next();
 713  
 
 714  24
                 Database database
 715  
                         = (Database) databases.get(databaseKey);
 716  24
                 if (DEFAULT_NAME.equals(databaseKey) && defaultDsfIsReference)
 717  
                 {
 718  
                     // the DataSourceFactory of the database with the name
 719  
                     // DEFAULT_NAME is just a reference to aynother entry.
 720  
                     // Do not close because this leads to closing
 721  
                     // the same DataSourceFactory twice.
 722  12
                     database.setDataSourceFactory(null);
 723  12
                     break;
 724  
                 }
 725  
 
 726  
                 try
 727  
                 {
 728  12
                     DataSourceFactory dataSourceFactory
 729  
                             = database.getDataSourceFactory();
 730  12
                     if (dataSourceFactory != null)
 731  
                     {
 732  6
                         dataSourceFactory.close();
 733  6
                         database.setDataSourceFactory(null);
 734  
                     }
 735  
                 }
 736  0
                 catch (TorqueException e)
 737  
                 {
 738  0
                     log.error("Error while closing the DataSourceFactory "
 739  
                             + databaseKey,
 740  
                             e);
 741  0
                     if (exception == null)
 742  
                     {
 743  0
                         exception = e;
 744  
                     }
 745  18
                 }
 746  6
             }
 747  12
         }
 748  12
         if (exception != null)
 749  
         {
 750  0
             throw exception;
 751  
         }
 752  12
         resetConfiguration();
 753  12
     }
 754  
 
 755  
     /**
 756  
      * Resets some internal configuration variables to
 757  
      * their defaults.
 758  
      */
 759  
     private void resetConfiguration()
 760  
     {
 761  48
         mapBuilderCache = Collections.synchronizedMap(new HashMap());
 762  48
         managers = new HashMap();
 763  48
         isInit = false;
 764  48
     }
 765  
 
 766  
     /**
 767  
      * Returns the default database map information.
 768  
      *
 769  
      * @return A DatabaseMap.
 770  
      * @throws TorqueException Any exceptions caught during processing will be
 771  
      *         rethrown wrapped into a TorqueException.
 772  
      */
 773  
     public DatabaseMap getDatabaseMap()
 774  
             throws TorqueException
 775  
     {
 776  0
         return getDatabaseMap(getDefaultDB());
 777  
     }
 778  
 
 779  
     /**
 780  
      * Returns the database map information. Name relates to the name
 781  
      * of the connection pool to associate with the map.
 782  
      *
 783  
      * @param name The name of the database corresponding to the
 784  
      *        <code>DatabaseMap</code> to retrieve.
 785  
      * @return The named <code>DatabaseMap</code>.
 786  
      * @throws TorqueException Any exceptions caught during processing will be
 787  
      *         rethrown wrapped into a TorqueException.
 788  
      */
 789  
     public DatabaseMap getDatabaseMap(String name)
 790  
             throws TorqueException
 791  
     {
 792  156
         if (name == null)
 793  
         {
 794  0
             throw new TorqueException ("DatabaseMap name was null!");
 795  
         }
 796  
 
 797  156
         Database database = getOrCreateDatabase(name);
 798  156
         return database.getDatabaseMap();
 799  
     }
 800  
 
 801  
     /**
 802  
      * Get the registered MapBuilders
 803  
      *
 804  
      * @return the MapBuilder cache
 805  
      * 
 806  
      */
 807  
     public Map getMapBuilders()
 808  
     {
 809  6
         return mapBuilderCache;
 810  
     }
 811  
 
 812  
     /**
 813  
      * Register a MapBuilder
 814  
      *
 815  
      * @param className the MapBuilder
 816  
      */
 817  
     public void registerMapBuilder(String className)
 818  
     {
 819  6
         mapBuilderCache.put(className, null);
 820  6
     }
 821  
 
 822  
     /**
 823  
      * Register a MapBuilder
 824  
      *
 825  
      * @param builder the instance of the MapBuilder
 826  
      * 
 827  
      */
 828  
     public void registerMapBuilder(MapBuilder builder)
 829  
     {
 830  0
         mapBuilderCache.put(builder.getClass().getName(), builder);
 831  0
     }
 832  
     
 833  
     /**
 834  
      * Get a MapBuilder
 835  
      *
 836  
      * @param className of the MapBuilder
 837  
      * @return A MapBuilder, not null
 838  
      * @throws TorqueException if the Map Builder cannot be instantiated
 839  
      * 
 840  
      */
 841  
     public MapBuilder getMapBuilder(String className)
 842  
         throws TorqueException
 843  
     {
 844  
         try
 845  
         {
 846  6
             MapBuilder mb = (MapBuilder)mapBuilderCache.get(className);
 847  
 
 848  6
             if (mb == null)
 849  
             {
 850  6
                 mb = (MapBuilder) Class.forName(className).newInstance();
 851  
                 // Cache the MapBuilder before it is built.
 852  6
                 mapBuilderCache.put(className, mb);
 853  
             }
 854  
 
 855  6
             if (mb.isBuilt())
 856  
             {
 857  0
                 return mb;
 858  
             }
 859  
 
 860  
             try
 861  
             {
 862  6
                 mb.doBuild();
 863  
             }
 864  0
             catch (Exception e)
 865  
             {
 866  
                 // remove the MapBuilder from the cache if it can't be built correctly
 867  0
                 mapBuilderCache.remove(className);
 868  0
                 throw e;
 869  6
             }
 870  
 
 871  6
             return mb;
 872  
         }
 873  0
         catch (Exception e)
 874  
         {
 875  0
             log.error("getMapBuilder failed trying to instantiate: "
 876  
                     + className, e);
 877  0
             throw new TorqueException(e);
 878  
         }
 879  
     }
 880  
     
 881  
     /**
 882  
      * This method returns a Connection from the default pool.
 883  
      *
 884  
      * @return The requested connection, never null.
 885  
      * @throws TorqueException Any exceptions caught during processing will be
 886  
      *         rethrown wrapped into a TorqueException.
 887  
      */
 888  
     public Connection getConnection()
 889  
             throws TorqueException
 890  
     {
 891  0
         return getConnection(getDefaultDB());
 892  
     }
 893  
 
 894  
     /**
 895  
      * Returns a database connection to the database with the key
 896  
      * <code>name</code>.
 897  
      * @param name The database name.
 898  
      * @return a database connection, never null.
 899  
      * @throws TorqueException If no DataSourceFactory is configured for the
 900  
      *         named database, the connection information is wrong, or the
 901  
      *         connection cannot be returned for any other reason.
 902  
      */
 903  
     public Connection getConnection(String name)
 904  
             throws TorqueException
 905  
     {
 906  0
         if (!Torque.isInit())
 907  
         {
 908  0
             throw new TorqueException("Torque is not initialized");
 909  
         }
 910  
         try
 911  
         {
 912  0
             return getDatabase(name)
 913  
                     .getDataSourceFactory()
 914  
                     .getDataSource()
 915  
                     .getConnection();
 916  
         }
 917  0
         catch (SQLException se)
 918  
         {
 919  0
             throw new TorqueException(se);
 920  
         }
 921  
     }
 922  
 
 923  
     /**
 924  
      * Returns the DataSourceFactory for the database with the name
 925  
      * <code>name</code>.
 926  
      *
 927  
      * @param name The name of the database to get the DSF for.
 928  
      * @return A DataSourceFactory object, never null.
 929  
      * @throws TorqueException if Torque is not initiliaized, or
 930  
      *         no DatasourceFactory is configured for the given name.
 931  
      */
 932  
     public DataSourceFactory getDataSourceFactory(String name)
 933  
             throws TorqueException
 934  
     {
 935  12
         Database database = getDatabase(name);
 936  
 
 937  12
         DataSourceFactory dsf = null;
 938  12
         if (database != null)
 939  
         {
 940  12
             dsf = database.getDataSourceFactory();
 941  
         }
 942  
 
 943  12
         if (dsf == null)
 944  
         {
 945  0
             throw new TorqueException(
 946  
                     "There was no DataSourceFactory "
 947  
                     + "configured for the connection " + name);
 948  
         }
 949  
 
 950  12
         return dsf;
 951  
     }
 952  
 
 953  
     /**
 954  
      * This method returns a Connection using the given parameters.
 955  
      * You should only use this method if you need user based access to the
 956  
      * database!
 957  
      *
 958  
      * @param name The database name.
 959  
      * @param username The name of the database user.
 960  
      * @param password The password of the database user.
 961  
      * @return A Connection.
 962  
      * @throws TorqueException Any exceptions caught during processing will be
 963  
      *         rethrown wrapped into a TorqueException.
 964  
      */
 965  
     public Connection getConnection(String name, String username,
 966  
             String password)
 967  
             throws TorqueException
 968  
     {
 969  0
         if (!Torque.isInit())
 970  
         {
 971  0
             throw new TorqueException("Torque is not initialized");
 972  
         }
 973  
         try
 974  
         {
 975  0
             return getDataSourceFactory(name)
 976  
                     .getDataSource().getConnection(username, password);
 977  
         }
 978  0
         catch (SQLException se)
 979  
         {
 980  0
             throw new TorqueException(se);
 981  
         }
 982  
     }
 983  
 
 984  
     /**
 985  
      * Returns the database adapter for a specific database.
 986  
      *
 987  
      * @param name the name of the database to get the adapter for.
 988  
      * @return The corresponding database adapter, or null if no database
 989  
      *         adapter is defined for the given database.
 990  
      * @throws TorqueException Any exceptions caught during processing will be
 991  
      *         rethrown wrapped into a TorqueException.
 992  
      */
 993  
     public DB getDB(String name) throws TorqueException
 994  
     {
 995  264
         Database database = getDatabase(name);
 996  264
         if (database == null)
 997  
         {
 998  0
             return null;
 999  
         }
 1000  264
         return database.getAdapter();
 1001  
     }
 1002  
 
 1003  
     ///////////////////////////////////////////////////////////////////////////
 1004  
 
 1005  
     /**
 1006  
      * Returns the name of the default database.
 1007  
      *
 1008  
      * @return name of the default DB, or null if Torque is not initialized yet
 1009  
      */
 1010  
     public String getDefaultDB()
 1011  
     {
 1012  294
         return defaultDBName;
 1013  
     }
 1014  
 
 1015  
     /**
 1016  
      * Closes a connection.
 1017  
      *
 1018  
      * @param con A Connection to close.
 1019  
      */
 1020  
     public void closeConnection(Connection con)
 1021  
     {
 1022  0
         if (con != null)
 1023  
         {
 1024  
             try
 1025  
             {
 1026  0
                 con.close();
 1027  
             }
 1028  0
             catch (SQLException e)
 1029  
             {
 1030  0
                 log.error("Error occured while closing connection.", e);
 1031  0
             }
 1032  
         }
 1033  0
     }
 1034  
 
 1035  
     /**
 1036  
      * Sets the current schema for a database connection
 1037  
      *
 1038  
      * @param name The database name.
 1039  
      * @param schema The current schema name.
 1040  
      * @throws TorqueException Any exceptions caught during processing will be
 1041  
      *         rethrown wrapped into a TorqueException.
 1042  
      */
 1043  
     public void setSchema(String name, String schema)
 1044  
             throws TorqueException
 1045  
     {
 1046  0
         getOrCreateDatabase(name).setSchema(schema);
 1047  0
     }
 1048  
 
 1049  
     /**
 1050  
      * This method returns the current schema for a database connection
 1051  
      *
 1052  
      * @param name The database name.
 1053  
      * @return The current schema name. Null means, no schema has been set.
 1054  
      * @throws TorqueException Any exceptions caught during processing will be
 1055  
      *         rethrown wrapped into a TorqueException.
 1056  
      */
 1057  
     public String getSchema(String name)
 1058  
         throws TorqueException
 1059  
     {
 1060  198
         Database database = getDatabase(name);
 1061  198
         if (database == null)
 1062  
         {
 1063  0
             return null;
 1064  
         }
 1065  198
         return database.getSchema();
 1066  
     }
 1067  
 
 1068  
     /**
 1069  
      * Returns the database for the key <code>databaseName</code>.
 1070  
      *
 1071  
      * @param databaseName the key to get the database for.
 1072  
      * @return the database for the specified key, or null if the database
 1073  
      *         does not exist.
 1074  
      * @throws TorqueException if Torque is not yet initialized.
 1075  
      */
 1076  
     public Database getDatabase(String databaseName) throws TorqueException
 1077  
     {
 1078  498
         if (!isInit())
 1079  
         {
 1080  0
             throw new TorqueException("Torque is not initialized.");
 1081  
         }
 1082  498
         return (Database) databases.get(databaseName);
 1083  
     }
 1084  
 
 1085  
     /**
 1086  
      * Returns a Map containing all Databases registered to Torque.
 1087  
      * The key of the Map is the name of the database, and the value is the
 1088  
      * database instance. <br/>
 1089  
      * Note that in the very special case where a new database which
 1090  
      * is not configured in Torque's configuration gets known to Torque
 1091  
      * at a later time, the returned map may change, and there is no way to
 1092  
      * protect you against this.
 1093  
      *
 1094  
      * @return a Map containing all Databases known to Torque, never null.
 1095  
      * @throws TorqueException if Torque is not yet initialized.
 1096  
      */
 1097  
     public Map getDatabases() throws TorqueException
 1098  
     {
 1099  12
         if (!isInit())
 1100  
         {
 1101  6
             throw new TorqueException("Torque is not initialized.");
 1102  
         }
 1103  6
         return Collections.unmodifiableMap(databases);
 1104  
     }
 1105  
 
 1106  
     /**
 1107  
      * Returns the database for the key <code>databaseName</code>.
 1108  
      * If no database is associated to the specified key,
 1109  
      * a new database is created, mapped to the specified key, and returned.
 1110  
      *
 1111  
      * @param databaseName the key to get the database for.
 1112  
      * @return the database associated with specified key, or the newly created
 1113  
      *         database, never null.
 1114  
      */
 1115  
     public Database getOrCreateDatabase(String databaseName)
 1116  
     {
 1117  246
         synchronized (databases)
 1118  
         {
 1119  246
             Database result = (Database) databases.get(databaseName);
 1120  246
             if (result == null)
 1121  
             {
 1122  60
                 result = new Database(databaseName);
 1123  60
                 databases.put(databaseName, result);
 1124  
             }
 1125  246
             return result;
 1126  0
         }
 1127  
     }
 1128  
 }

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