Coverage Report - org.kuali.rice.core.database.PrimaryDataSourceFactoryBean
 
Classes in this File Line Coverage Branch Coverage Complexity
PrimaryDataSourceFactoryBean
0%
0/101
0%
0/34
1.875
 
 1  
 /*
 2  
  * Copyright 2007 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  * http://www.opensource.org/licenses/ecl2.php
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.kuali.rice.core.database;
 17  
 
 18  
 import java.util.ArrayList;
 19  
 import java.util.List;
 20  
 
 21  
 import javax.naming.NamingException;
 22  
 import javax.sql.DataSource;
 23  
 
 24  
 import org.apache.commons.lang.StringUtils;
 25  
 import org.kuali.rice.core.config.Config;
 26  
 import org.kuali.rice.core.config.ConfigContext;
 27  
 import org.kuali.rice.core.config.ConfigurationException;
 28  
 import org.kuali.rice.core.lifecycle.Lifecycle;
 29  
 import org.kuali.rice.core.util.RiceConstants;
 30  
 import org.springframework.beans.factory.config.AbstractFactoryBean;
 31  
 import org.springframework.jndi.JndiTemplate;
 32  
 
 33  
 /**
 34  
  * A class that can be used to load the primary datasource for a Rice module from an object in the Config system or from a
 35  
  * JNDI url specified by the Configuration system. By default, it loads these values from the following properties if the
 36  
  * <code>useNonTransactionalDataSource</code> param is not set or is set to false:
 37  
  * <ul>
 38  
  * <li>{@link RiceConstants#DATASOURCE_OBJ}</li>
 39  
  * <li>{@link RiceConstants#DATASOURCE_JNDI}</li>
 40  
  * </ul>
 41  
  * If the <code>useNonTransactionalDataSource</code> param is set to true the following properties will be used:<br>
 42  
  * <br>
 43  
  * <ul>
 44  
  * <li>{@link RiceConstants#NON_TRANSACTIONAL_DATASOURCE_OBJ}</li>
 45  
  * <li>{@link RiceConstants#NON_TRANSACTIONAL_DATASOURCE_JNDI}</li>
 46  
  * </ul>
 47  
  * If the <code>server</code> param is set to true, the following properties will be added to the end of the preferred lists:<br>
 48  
  * <br>
 49  
  * <ul>
 50  
  * <li>{@link RiceConstants#SERVER_DATASOURCE_OBJ}</li>
 51  
  * <li>{@link RiceConstants#SERVER_DATASOURCE_JNDI}</li> 
 52  
  * <p>
 53  
  * The config properties checked can be overridden by setting values into the list parameters
 54  
  * <code>preferredDataSourceParams</code> and <code>preferredDataSourceJndiParams</code>
 55  
  * 
 56  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 57  
  */
 58  
 public class PrimaryDataSourceFactoryBean extends AbstractFactoryBean {
 59  
 
 60  
     private static final String DEFAULT_DATASOURCE_PARAM = RiceConstants.DATASOURCE_OBJ;
 61  
     private static final String DEFAULT_SERVER_DATASOURCE_PARAM = RiceConstants.SERVER_DATASOURCE_OBJ;
 62  
     private static final String DEFAULT_NONTRANSACTIONAL_DATASOURCE_PARAM = RiceConstants.NON_TRANSACTIONAL_DATASOURCE_OBJ;
 63  
     private static final String DEFAULT_DATASOURCE_JNDI_PARAM = RiceConstants.DATASOURCE_JNDI;
 64  
     private static final String DEFAULT_SERVER_DATASOURCE_JNDI_PARAM = RiceConstants.SERVER_DATASOURCE_JNDI;
 65  
     private static final String DEFAULT_NONTRANSACTIONAL_DATASOURCE_JNDI_PARAM = RiceConstants.NON_TRANSACTIONAL_DATASOURCE_JNDI;
 66  
 
 67  
     private JndiTemplate jndiTemplate;
 68  0
     private boolean nonTransactionalDataSource = false;
 69  0
     private String defaultDataSourceParam = DEFAULT_DATASOURCE_PARAM;
 70  0
     private String defaultNonTransactionalDataSourceParam = DEFAULT_NONTRANSACTIONAL_DATASOURCE_PARAM;
 71  0
     private String defaultDataSourceJndiParam = DEFAULT_DATASOURCE_JNDI_PARAM;
 72  0
     private String defaultNonTransactionalDataSourceJndiParam = DEFAULT_NONTRANSACTIONAL_DATASOURCE_JNDI_PARAM;
 73  0
     private List<String> preferredDataSourceParams = new ArrayList<String>();
 74  0
     private List<String> preferredDataSourceJndiParams = new ArrayList<String>();
 75  0
     private boolean serverDataSource = false;
 76  0
     private boolean nullAllowed = false;
 77  
     
 78  0
     public PrimaryDataSourceFactoryBean() {
 79  0
         setSingleton(true);
 80  0
     }
 81  
 
 82  
     public Class<DataSource> getObjectType() {
 83  0
         return DataSource.class;
 84  
     }
 85  
     
 86  
     @Override
 87  
         public void afterPropertiesSet() throws Exception {
 88  0
             if (serverDataSource) {
 89  0
                     getPreferredDataSourceParams().add(DEFAULT_SERVER_DATASOURCE_PARAM);
 90  0
                     getPreferredDataSourceJndiParams().add(DEFAULT_SERVER_DATASOURCE_JNDI_PARAM);
 91  
             }
 92  0
             super.afterPropertiesSet();
 93  0
         }
 94  
 
 95  
         @Override
 96  
     protected Object createInstance() throws Exception {
 97  0
         Config config = ConfigContext.getCurrentContextConfig();
 98  0
         DataSource dataSource = createDataSource(config);
 99  0
         if (dataSource == null && !isNullAllowed()) {
 100  0
                 throw new ConfigurationException("Failed to configure the Primary Data Source.");
 101  
         }
 102  0
         return dataSource;
 103  
     }
 104  
 
 105  
     protected String getDefaultDataSourceParamByType() {
 106  0
         return (nonTransactionalDataSource) ? getDefaultNonTransactionalDataSourceParam() : getDefaultDataSourceParam();
 107  
     }
 108  
 
 109  
     protected String getDefaultDataSourceJndiParamByType() {
 110  0
         return (nonTransactionalDataSource) ? getDefaultNonTransactionalDataSourceJndiParam() : getDefaultDataSourceJndiParam();
 111  
     }
 112  
 
 113  
     protected DataSource createDataSource(Config config) throws Exception {
 114  0
         DataSource dataSource = loadPreferredDataSourceFromConfig(config);
 115  0
         if (dataSource == null) {
 116  
 
 117  0
             Object dataSourceObject = config.getObject(getDefaultDataSourceParamByType());
 118  0
             if (dataSourceObject != null) {
 119  0
                 validateDataSource(getDefaultDataSourceParamByType(), dataSourceObject);
 120  0
                 dataSource = (DataSource) dataSourceObject;
 121  
             } else {
 122  0
                 dataSource = getDataSourceFromJndi(config, getDefaultDataSourceJndiParamByType());
 123  
             }
 124  
         }
 125  0
         return dataSource;
 126  
     }
 127  
 
 128  
     protected DataSource loadPreferredDataSourceFromConfig(Config config) {
 129  0
         for (String dataSourceParam : getPreferredDataSourceParams()) {
 130  0
             Object dataSource = config.getObject(dataSourceParam);
 131  0
             if (dataSource != null) {
 132  0
                 validateDataSource(dataSourceParam, dataSource);
 133  0
                 return (DataSource) dataSource;
 134  
             }
 135  0
         }
 136  0
         if (this.jndiTemplate == null) {
 137  0
             this.jndiTemplate = new JndiTemplate();
 138  
         }
 139  0
         for (String dataSourceJndiParam : getPreferredDataSourceJndiParams()) {
 140  0
             DataSource dataSource = getDataSourceFromJndi(config, dataSourceJndiParam);
 141  0
             if (dataSource != null) {
 142  0
                 return dataSource;
 143  
             }
 144  0
         }
 145  0
         return null;
 146  
     }
 147  
 
 148  
     protected void validateDataSource(String paramName, Object dataSourceObject) {
 149  0
         if (!(dataSourceObject instanceof DataSource)) {
 150  0
             throw new ConfigurationException("DataSource configured for parameter '" + paramName + "' was not an instance of DataSource.  Was instead " + dataSourceObject.getClass().getName());
 151  
         }
 152  0
     }
 153  
 
 154  
     protected DataSource getDataSourceFromJndi(Config config, String dataSourceJndiParam) {
 155  0
         String jndiName = config.getProperty(dataSourceJndiParam);
 156  0
         if (!StringUtils.isBlank(jndiName)) {
 157  
             try {
 158  0
                 Object dataSource = getJndiTemplate().lookup(jndiName, DataSource.class);
 159  0
                 if (dataSource != null) {
 160  0
                     validateDataSource(dataSourceJndiParam, dataSource);
 161  0
                     return (DataSource) dataSource;
 162  
                 }
 163  0
             } catch (NamingException e) {
 164  0
                 throw new ConfigurationException("Could not locate the DataSource at the given JNDI location: '" + jndiName + "'", e);
 165  0
             }
 166  
         }
 167  0
         return null;
 168  
     }
 169  
 
 170  
     protected void destroyInstance(Object instance) throws Exception {
 171  0
         if (instance instanceof Lifecycle) {
 172  0
             ((Lifecycle) instance).stop();
 173  
         }
 174  0
     }
 175  
 
 176  
     protected String getStringProperty(Config config, String propertyName) {
 177  0
         String data = config.getProperty(propertyName);
 178  0
         if (StringUtils.isEmpty(data)) {
 179  0
             throw new ConfigurationException("Could not locate a value for the given property '" + propertyName + "'.");
 180  
         }
 181  0
         return data;
 182  
     }
 183  
 
 184  
     protected int getIntProperty(Config config, String propertyName) {
 185  0
         String data = getStringProperty(config, propertyName);
 186  
         try {
 187  0
             int intData = Integer.parseInt(data);
 188  0
             return intData;
 189  0
         } catch (NumberFormatException e) {
 190  0
             throw new ConfigurationException("The given property '" + propertyName + "' was not a valid integer.  Value was '" + data + "'");
 191  
         }
 192  
     }
 193  
 
 194  
     public JndiTemplate getJndiTemplate() {
 195  0
         return this.jndiTemplate;
 196  
     }
 197  
 
 198  
     public void setJndiTemplate(JndiTemplate jndiTemplate) {
 199  0
         this.jndiTemplate = jndiTemplate;
 200  0
     }
 201  
 
 202  
     public String getDefaultDataSourceJndiParam() {
 203  0
         return defaultDataSourceJndiParam;
 204  
     }
 205  
 
 206  
     public void setDefaultDataSourceJndiParam(String defaultDataSourceJndiParam) {
 207  0
         this.defaultDataSourceJndiParam = defaultDataSourceJndiParam;
 208  0
     }
 209  
 
 210  
     public String getDefaultNonTransactionalDataSourceJndiParam() {
 211  0
         return defaultNonTransactionalDataSourceJndiParam;
 212  
     }
 213  
 
 214  
     public void setDefaultNonTransactionalDataSourceJndiParam(String defaultNonTransactionalDataSourceJndiParam) {
 215  0
         this.defaultNonTransactionalDataSourceJndiParam = defaultNonTransactionalDataSourceJndiParam;
 216  0
     }
 217  
 
 218  
     public String getDefaultDataSourceParam() {
 219  0
         return defaultDataSourceParam;
 220  
     }
 221  
 
 222  
     public void setDefaultDataSourceParam(String defaultDataSourceParam) {
 223  0
         this.defaultDataSourceParam = defaultDataSourceParam;
 224  0
     }
 225  
 
 226  
     public String getDefaultNonTransactionalDataSourceParam() {
 227  0
         return defaultNonTransactionalDataSourceParam;
 228  
     }
 229  
 
 230  
     public void setDefaultNonTransactionalDataSourceParam(String defaultNonTransactionalDataSourceParam) {
 231  0
         this.defaultNonTransactionalDataSourceParam = defaultNonTransactionalDataSourceParam;
 232  0
     }
 233  
 
 234  
     public List<String> getPreferredDataSourceJndiParams() {
 235  0
         return preferredDataSourceJndiParams;
 236  
     }
 237  
 
 238  
     public void setPreferredDataSourceJndiParams(List<String> preferredDataSourceJndiParams) {
 239  0
         this.preferredDataSourceJndiParams = preferredDataSourceJndiParams;
 240  0
     }
 241  
 
 242  
     public List<String> getPreferredDataSourceParams() {
 243  0
         return preferredDataSourceParams;
 244  
     }
 245  
 
 246  
     public void setPreferredDataSourceParams(List<String> preferredDataSourceParams) {
 247  0
         this.preferredDataSourceParams = preferredDataSourceParams;
 248  0
     }
 249  
 
 250  
     public void setNonTransactionalDataSource(boolean nonTransactionalDataSource) {
 251  0
         this.nonTransactionalDataSource = nonTransactionalDataSource;
 252  0
     }
 253  
 
 254  
         public boolean isServerDataSource() {
 255  0
                 return this.serverDataSource;
 256  
         }
 257  
 
 258  
         public void setServerDataSource(boolean serverDataSource) {
 259  0
                 this.serverDataSource = serverDataSource;
 260  0
         }
 261  
 
 262  
         public boolean isNullAllowed() {
 263  0
                 return this.nullAllowed;
 264  
         }
 265  
 
 266  
         public void setNullAllowed(boolean nullAllowed) {
 267  0
                 this.nullAllowed = nullAllowed;
 268  0
         }
 269  
 
 270  
 }