Clover coverage report - JFox Service-Oriented Application Framework - 1.0-RC3
Coverage timestamp: 星期三 二月 15 2006 18:10:22 CST
file stats: LOC: 263   Methods: 7
NCLOC: 130   Classes: 1
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
DataSourceFactory.java 46.7% 75% 100% 67.4%
coverage coverage
 1   
 /**
 2   
  * @(#) DataSourceFactory.java
 3   
  * 
 4   
  * JFoxSOAF, Service-Oriented Application Framework
 5   
  * 
 6   
  * Copyright(c) JFoxSOAF Team
 7   
  * 
 8   
  * Licensed under the GNU LGPL, Version 2.1 (the "License"); 
 9   
  * you may not use this file except in compliance with the License. 
 10   
  * You may obtain a copy of the License at  
 11   
  * 
 12   
  * http://www.gnu.org/copyleft/lesser.html
 13   
  * 
 14   
  * Unless required by applicable law or agreed to in writing, software
 15   
  * distributed under the License is distributed on an "AS IS" BASIS, 
 16   
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 17   
  * See the License for the specific language governing permissions and 
 18   
  * limitations under the License. 
 19   
  * 
 20   
  * For more information, please visit:
 21   
  * http://www.jfox.cn/confluence/display/JFoxSOAF/Home
 22   
  * http://www.huihoo.org/jfox/jfoxsoaf
 23   
  */
 24   
 
 25   
 package org.huihoo.jfox.soaf.services.jdbc;
 26   
 
 27   
 import java.io.IOException;
 28   
 import java.io.InputStream;
 29   
 import java.security.AccessController;
 30   
 import java.security.PrivilegedAction;
 31   
 import java.sql.SQLException;
 32   
 import java.util.Enumeration;
 33   
 import java.util.Hashtable;
 34   
 import java.util.Properties;
 35   
 
 36   
 import javax.sql.DataSource;
 37   
 
 38   
 import org.huihoo.jfox.soaf.exception.DataSourceConfigurationException;
 39   
 import org.huihoo.jfox.soaf.util.resource.ResourceHelper;
 40   
 
 41   
 /**
 42   
  * <p>
 43   
  * Factory for creating database connection instances, with discovery and
 44   
  * configuration features
 45   
  * </p>
 46   
  * 
 47   
  * @author <a href="mailto:founder_chen@yahoo.com.cn">Peter Cheng </a>
 48   
  * @version $Revision: 1.6 $ $Date: 2005/05/22 06:49:48 $
 49   
  * @version Revision: 1.0
 50   
  */
 51   
 
 52   
 public abstract class DataSourceFactory {
 53   
 
 54   
     /**
 55   
      * Protected constructor that is not available for public use.
 56   
      */
 57  8
     protected DataSourceFactory() {
 58   
     }
 59   
 
 60   
     /**
 61   
      * The previously constructed <code>LogFactory</code> instances, keyed by
 62   
      * the <code>ClassLoader</code> with which it was created.
 63   
      */
 64   
     protected static Hashtable factories = new Hashtable();
 65   
 
 66   
     /**
 67   
      * Get singlton database connection instance.
 68   
      */
 69   
     public abstract DataSource getInstance()
 70   
             throws DataSourceConfigurationException, SQLException;
 71   
 
 72   
     /**
 73   
      * Return the configuration attribute with the specified name (if any), or
 74   
      * <code>null</code> if there is no such attribute.
 75   
      * 
 76   
      * @param name Name of the attribute to return
 77   
      */
 78   
     public abstract Object getAttribute(String name);
 79   
 
 80   
     /**
 81   
      * Return an array containing the names of all currently defined
 82   
      * configuration attributes. If there are no such attributes, a zero length
 83   
      * array is returned.
 84   
      */
 85   
     public abstract String[] getAttributeNames();
 86   
 
 87   
     /**
 88   
      * Remove any configuration attribute associated with the specified name. If
 89   
      * there is no such attribute, no action is taken.
 90   
      * 
 91   
      * @param name Name of the attribute to remove
 92   
      */
 93   
     public abstract void removeAttribute(String name);
 94   
 
 95   
     /**
 96   
      * Set the configuration attribute with the specified name. Calling this
 97   
      * with a <code>null</code> value is equivalent to calling
 98   
      * <code>removeAttribute(name)</code>.
 99   
      * 
 100   
      * @param name Name of the attribute to set
 101   
      * @param value Value of the attribute to set, or <code>null</code> to
 102   
      *            remove any setting for this attribute
 103   
      */
 104   
     public abstract void setAttribute(String name, Object value);
 105   
 
 106  87
     public static DataSourceFactory getFactory()
 107   
             throws DataSourceConfigurationException {
 108   
         // Return any previously registered factory for this class loader
 109  87
         DataSourceFactory factory = getCachedFactory(DataSourceFactory.class
 110   
                 .getClassLoader());
 111   
 
 112  87
         if (factory != null) {
 113  83
             return factory;
 114   
         }
 115   
 
 116   
         // Load properties file
 117  4
         Properties props = null;
 118  4
         try {
 119  4
             InputStream stream = ResourceHelper
 120   
                     .getResourceAsStream(DatabaseConstant.JDBC_FACTORY_PROPERTIES);
 121   
 
 122  4
             if (stream != null) {
 123  4
                 props = new Properties();
 124  4
                 props.load(stream);
 125  4
                 stream.close();
 126   
             }
 127   
         } catch (IOException e) {
 128  0
             throw new DataSourceConfigurationException(
 129   
                     "Load Database configuration IO exception " + e);
 130   
         } catch (SecurityException e) {
 131  0
             throw new DataSourceConfigurationException(
 132   
                     "Database configuration access security exception " + e);
 133   
         }
 134   
 
 135   
         // Second try a properties file.
 136  4
         if (factory == null && props != null) {
 137  4
             String factoryClass = props
 138   
                     .getProperty(DatabaseConstant.JDBC_DATABASE_FACTORY);
 139  4
             if (factoryClass != null && !factoryClass.equals("")) {
 140  4
                 factory = newFactory(factoryClass, DataSourceFactory.class
 141   
                         .getClassLoader());
 142   
             }
 143   
         }
 144   
 
 145   
         // Third, try the fallback implementation class
 146  4
         if (factory == null) {
 147  0
             factory = newFactory(DatabaseConstant.JDBC_DEFAULT_FACTORY,
 148   
                     DataSourceFactory.class.getClassLoader());
 149   
         }
 150   
 
 151  4
         if (factory != null) {
 152   
             /**
 153   
              * Always cache using context class loader..
 154   
              */
 155  4
             cacheFactory(DataSourceFactory.class.getClassLoader(), factory);
 156   
 
 157  4
             if (props != null) {
 158  4
                 Enumeration names = props.propertyNames();
 159  4
                 while (names.hasMoreElements()) {
 160  80
                     String name = (String) names.nextElement();
 161  80
                     String value = props.getProperty(name);
 162  80
                     factory.setAttribute(name, value);
 163   
                 }
 164   
             }
 165   
         }
 166   
 
 167  4
         return factory;
 168   
     }
 169   
 
 170   
     /**
 171   
      * Check cached factories (keyed by classLoader)
 172   
      */
 173  87
     private static DataSourceFactory getCachedFactory(
 174   
             ClassLoader contextClassLoader) {
 175  87
         DataSourceFactory factory = null;
 176   
 
 177  87
         if (contextClassLoader != null) {
 178  87
             factory = (DataSourceFactory) factories.get(contextClassLoader);
 179   
         }
 180   
 
 181  87
         return factory;
 182   
     }
 183   
 
 184  4
     private static void cacheFactory(ClassLoader classLoader,
 185   
             DataSourceFactory factory) {
 186  4
         if (classLoader != null && factory != null) {
 187  4
             factories.put(classLoader, factory);
 188   
         }
 189   
     }
 190   
 
 191   
     /**
 192   
      * Return a new instance of the specified <code>LogFactory</code>
 193   
      * implementation class, loaded by the specified class loader. If that
 194   
      * fails, try the class loader used to load this (abstract) LogFactory.
 195   
      * 
 196   
      * @param factoryClass Fully qualified name of the <code>LogFactory</code>
 197   
      *            implementation class
 198   
      * @param classLoader ClassLoader from which to load this class
 199   
      * @exception DataSourceConfigException if a suitable instance cannot be
 200   
      *                created
 201   
      */
 202  5
     protected static DataSourceFactory newFactory(final String factoryClass,
 203   
             final ClassLoader classLoader)
 204   
             throws DataSourceConfigurationException {
 205  5
         Object result = AccessController.doPrivileged(new PrivilegedAction() {
 206   
 
 207  5
             public Object run() {
 208  5
                 try {
 209  5
                     if (classLoader != null) {
 210  5
                         try {
 211  5
                             return classLoader.loadClass(factoryClass)
 212   
                                     .newInstance();
 213   
                         } catch (ClassNotFoundException ex) {
 214  0
                             if (classLoader == DataSourceFactory.class
 215   
                                     .getClassLoader()) {
 216   
                                 // Nothing more to try, onwards.
 217  0
                                 throw ex;
 218   
                             }
 219   
                             // ignore exception, continue
 220   
                         } catch (NoClassDefFoundError e) {
 221  0
                             if (classLoader == DataSourceFactory.class
 222   
                                     .getClassLoader()) {
 223  0
                                 throw e;
 224   
                             }
 225   
 
 226   
                         } catch (ClassCastException e) {
 227   
 
 228  0
                             if (classLoader == DataSourceFactory.class
 229   
                                     .getClassLoader()) {
 230  0
                                 throw e;
 231   
                             }
 232   
                         }
 233   
                     }
 234  0
                     return Class.forName(factoryClass).newInstance();
 235   
                 } catch (Exception e) {
 236  0
                     return new DataSourceConfigurationException(e);
 237   
                 }
 238   
             }
 239   
         });
 240   
 
 241  5
         if (result instanceof DataSourceConfigurationException) {
 242  0
             throw (DataSourceConfigurationException) result;
 243   
         }
 244   
 
 245  5
         return (DataSourceFactory) result;
 246   
     }
 247   
 
 248   
     /**
 249   
      * Retrive concreate datasource.
 250   
      * 
 251   
      * @return PoolDataSource
 252   
      * @throws DataSourceConfigurationException
 253   
      */
 254  85
     public static DataSource getDataSource()
 255   
             throws DataSourceConfigurationException {
 256  85
         try {
 257  85
             return getFactory().getInstance();
 258   
         } catch (Exception e) {
 259  0
             throw new DataSourceConfigurationException(e.getMessage(), e);
 260   
         }
 261   
     }
 262   
 
 263   
 }