Coverage report

  %line %branch
ca.spaz.cron.datasource.sql.ConnectionManager
61% 
80% 

 1  
 /*
 2  
  *******************************************************************************
 3  
  * Copyright (c) 2005 Chris Rose and AIMedia
 4  
  * All rights reserved. ConnectionManager and the accompanying materials
 5  
  * are made available under the terms of the Common Public License v1.0
 6  
  * which accompanies this distribution, and is available at
 7  
  * http://www.eclipse.org/legal/cpl-v10.html
 8  
  * 
 9  
  * Contributors:
 10  
  *     Chris Rose
 11  
  *******************************************************************************/
 12  
 package ca.spaz.cron.datasource.sql;
 13  
 
 14  
 import java.sql.*;
 15  
 import java.util.*;
 16  
 
 17  
 import org.apache.log4j.Logger;
 18  
 
 19  
 import ca.spaz.cron.CRONConfiguration;
 20  
 import ca.spaz.util.ToolBox;
 21  
 
 22  
 /**
 23  
  * Class for JDBC connection management. Provides information about available
 24  
  * datasources, and provides Connection objects to calling classes that are
 25  
  * guaranteed to be working.
 26  
  * 
 27  
  * @author Chris Rose
 28  
  */
 29  14
 public class ConnectionManager {
 30  
 
 31  
    /**
 32  
     * Implementation of the DatabaseID interface for DB name and DB ID
 33  
     * 
 34  
     * @author Chris Rose
 35  
     */
 36  
    private static class DatabaseIDImpl implements DatabaseID {
 37  
 
 38  
       private String id;
 39  
 
 40  
       private String name;
 41  
 
 42  
       /**
 43  
        * Create a new instance, with the supplied DB ID and name.
 44  
        * 
 45  
        * @param dbID
 46  
        *           the ID of the database in the properties file
 47  
        * @param dbName
 48  
        *           the human-readable name of the database.
 49  
        */
 50  
       public DatabaseIDImpl(String dbID, String dbName) {
 51  
          this.id = dbID;
 52  
          this.name = dbName;
 53  
       }
 54  
 
 55  
       /*
 56  
        * (non-Javadoc)
 57  
        * 
 58  
        * @see ca.spaz.cron.database.DatabaseID#getID()
 59  
        */
 60  
       public String getID() {
 61  
          return id;
 62  
       }
 63  
 
 64  
       /*
 65  
        * (non-Javadoc)
 66  
        * 
 67  
        * @see ca.spaz.cron.database.DatabaseID#getName()
 68  
        */
 69  
       public String getName() {
 70  
          return name;
 71  
       }
 72  
 
 73  
       /*
 74  
        * (non-Javadoc)
 75  
        * 
 76  
        * @see java.lang.Object#toString()
 77  
        */
 78  
       public String toString() {
 79  
          return name;
 80  
       }
 81  
 
 82  
    }
 83  
 
 84  
    private static List dbIDList;
 85  
 
 86  
    private static Map instanceMap;
 87  
 
 88  20
    private static final Logger logger = Logger
 89  20
          .getLogger(ConnectionManager.class);
 90  
 
 91  
    /**
 92  
     * Get the human-friendly name for a connection ID
 93  
     * 
 94  
     * @param connectionID
 95  
     *           the ID to get the name for
 96  
     * @return the name of the Connection, or an error message.
 97  
     */
 98  
    static String getConnectionName(String connectionID) {
 99  884
       return getProperties().getProperty("db." + connectionID + ".name",
 100  364
             "Missing DB Name");
 101  
    }
 102  
 
 103  
    /**
 104  
     * Retrieve a list of available database IDs.
 105  
     * 
 106  
     * @return a <code>List</code> containing <code>DatabaseID</code>
 107  
     *         implementations for every available user datasource.
 108  
     */
 109  
    public static List getDatabaseIDs() {
 110  0
       if (null == dbIDList) {
 111  0
          dbIDList = new ArrayList();
 112  0
          String[] ids = getProperties().getProperty("db.dblist", "").split(",");
 113  0
          for (int i = 0; i < ids.length; i++) {
 114  0
             dbIDList.add(new DatabaseIDImpl(ids[i], getConnectionName(ids[i])));
 115  
          }
 116  
       }
 117  0
       return dbIDList;
 118  
    }
 119  
 
 120  
    /**
 121  
     * Get an instance of a ConnectionManager for a particular dbID.
 122  
     * 
 123  
     * @param dbID
 124  
     *           the ID of the connection
 125  
     * @return a <code>ConnectionManager</code> for the ID
 126  
     */
 127  
    public static ConnectionManager getInstance(String dbID) {
 128  1054
       ConnectionManager dbInstance = (ConnectionManager) getInstanceMap().get(
 129  434
             dbID);
 130  620
       if (null == dbInstance) {
 131  30
          dbInstance = new ConnectionManager(dbID);
 132  30
          getInstanceMap().put(dbID, dbInstance);
 133  
       }
 134  620
       return dbInstance;
 135  
    }
 136  
 
 137  
    private static Map getInstanceMap() {
 138  680
       if (null == instanceMap) {
 139  20
          instanceMap = new HashMap();
 140  
       }
 141  680
       return instanceMap;
 142  
    }
 143  
 
 144  
    /**
 145  
     * @return
 146  
     */
 147  
    private static CRONConfiguration getProperties() {
 148  1140
       return CRONConfiguration.getInstance();
 149  
    }
 150  
 
 151  
    /**
 152  
     * @param foodDB
 153  
     */
 154  
    private static void registerInstance(ConnectionManager foodDB) {
 155  30
       getInstanceMap().put(foodDB.dbID, foodDB);
 156  30
    }
 157  
 
 158  
    private Connection dbc;
 159  
 
 160  
    private String dbID;
 161  
 
 162  
    private List listeners;
 163  
 
 164  30
    private ConnectionManager(String dbID) {
 165  30
       this.dbID = dbID;
 166  30
       registerInstance(this);
 167  30
    }
 168  
 
 169  
    /**
 170  
     * Add an observer for notification when the database connection is made. If
 171  
     * the database is already connected, fires a notification immediately.
 172  
     * 
 173  
     * @param observer
 174  
     *           the Observer.
 175  
     */
 176  
    public void addConnectionStatusListener(IConnectionStatusObserver observer) {
 177  0
       getListeners().add(observer);
 178  0
       if (getInstanceMap().containsKey(dbID)) {
 179  0
          observer.connectionMade(dbID);
 180  
       }
 181  0
    }
 182  
 
 183  
    /**
 184  
     * Get the database connection. Lazy initializer.
 185  
     * 
 186  
     * @return the connection to the food database or null if there is no
 187  
     *         connection possible.
 188  
     */
 189  
    public Connection getConnection() {
 190  
       try {
 191  
          /*
 192  
           * This is a test to determine if the connection is 'live' -- if it is
 193  
           * not, we'll be replacing it with a new one.
 194  
           */
 195  620
          if (dbc != null) {
 196  590
             dbc.createStatement().execute(
 197  
                   "CREATE TABLE _garbage___(id char(1))");
 198  0
             dbc.createStatement().execute("DROP TABLE _garbage___");
 199  
          }
 200  590
       } catch (SQLException e) {
 201  590
          if (logger.isDebugEnabled()) {
 202  0
             logger.debug("getConnection() - lost working connection to DB ["
 203  
                   + dbID + "]", e);
 204  
          }
 205  590
          dbc = null;
 206  9
       }
 207  620
       if (dbc == null) {
 208  
          /*
 209  
           * Acquire a connection based on values set in db.properties
 210  
           */
 211  620
          CRONConfiguration p = getProperties();
 212  
          /*
 213  
           * Load the db properties. Defaults are specified for server mode
 214  
           * operation.
 215  
           */
 216  620
          String serverMode = "";
 217  620
          serverMode = p.getProperty("db." + dbID);
 218  620
          if (null == serverMode) {
 219  0
             logger.error("Incomplete properties -- missing datasource for "
 220  
                   + dbID);
 221  
          }
 222  620
          String classname = p.getProperty("db." + serverMode + ".driverclass");
 223  620
          String url = p.getProperty("db." + serverMode + ".url");
 224  620
          int idx = url.indexOf("${APP_HOME}");
 225  620
          if (idx >= 0) {
 226  0
             String oldURL = url;
 227  0
             url = oldURL.substring(0, idx) + ToolBox.getUserAppDirectory("cronometer").getAbsolutePath() + oldURL.substring(idx + "${APP_HOME}".length());
 228  
          }
 229  620
          String username = p.getProperty("db." + serverMode + ".username");
 230  620
          String password = p.getProperty("db." + serverMode + ".password");
 231  620
          if (null == url || class="keyword">null == classname || class="keyword">null == username
 232  434
                || null == password) {
 233  0
             logger.error("Incomplete properties for [" + dbID + "] source "
 234  
                   + serverMode);
 235  0
             return null;
 236  
          }
 237  
          try {
 238  620
             if (logger.isInfoEnabled()) {
 239  0
                logger
 240  
                      .info("getConnection() - Acquiring db connection to : url = "
 241  
                            + url);
 242  
             }
 243  
 
 244  620
             Class.forName(classname).newInstance();
 245  620
             dbc = DriverManager.getConnection(url, username, password);
 246  620
             notifyObservers();
 247  0
          } catch (Exception e) {
 248  0
             logger.error("getConnection()", e);
 249  186
          }
 250  
       }
 251  620
       return dbc;
 252  
    }
 253  
 
 254  
    private List getListeners() {
 255  620
       if (null == listeners) {
 256  30
          listeners = new ArrayList();
 257  
       }
 258  620
       return listeners;
 259  
    }
 260  
 
 261  
    private void notifyObservers() {
 262  1054
       for (Iterator iter = getListeners().iterator(); iter.hasNext();) {
 263  0
          IConnectionStatusObserver element = (IConnectionStatusObserver) iter
 264  
                .next();
 265  0
          element.connectionMade(dbID);
 266  0
       }
 267  620
    }
 268  
 
 269  
    /**
 270  
     * Remove an observer from this ConnectionManager
 271  
     * 
 272  
     * @param observer
 273  
     *           the Observer to remove.
 274  
     */
 275  
    public void removeConnectionStatusListener(IConnectionStatusObserver observer) {
 276  0
       getListeners().remove(observer);
 277  0
    }
 278  
 
 279  
 }

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