Coverage Report - com.sourceforge.jpatterns.core.configuration.PropertiesManagerImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
PropertiesManagerImpl
84% 
88% 
0
 
 1  
 package com.sourceforge.jpatterns.core.configuration;
 2  
 
 3  
 import com.sourceforge.jpatterns.core.configuration.exceptions.JPInitializationException;
 4  
 import com.sourceforge.jpatterns.utils.JPatternsPropsUtils;
 5  
 import com.zmicer.utils.*;
 6  
 import org.apache.log4j.Logger;
 7  
 
 8  
 import java.util.Enumeration;
 9  
 import java.util.HashSet;
 10  
 import java.util.ResourceBundle;
 11  
 import java.util.Set;
 12  
 
 13  
 /**
 14  
  * This class manages deals with the properties files JPatterns uses.
 15  
  * <br/>
 16  
  * Please do not put here any functionality which could be customizable later. Only the functionality fitting the approach:
 17  
  * we have default and custom properties files which are taken from the classpath. In the case custom configuration contains the same
 18  
  * keys - they would override the default configuration.
 19  
  * <br/>
 20  
  * Potentially the part of this PropertyManager could be used at the JInit.
 21  
  * <br/>
 22  
  * Please be noticed the very important method is the following:
 23  
  * <code>com.sourceforge.jpatterns.core.configuration.PropertiesManagerImpl#getBundle(java.lang.String)</code>, and this method
 24  
  * firstly checks the default configuration, and then checks the overriden, custom configuration.
 25  
  * todo [zmicer]: think if this could be moved to the common functionality. Think over the PropertiesProvider class - why do we really need\
 26  
  * two these classes? Please finish investigating.
 27  
  *
 28  
  * todo [zmicer]: introduce the opportunity to setup the necessary names from outside - it would allow us to use this approach as the common
 29  
  * functionality.
 30  
  * todo [zmicer]: please check in which way the is used here: 0001\src\testdata\jpatterns_custom.properties
 31  
  *
 32  
  * $Author:: zmicer             $<br/>
 33  
  * $Rev:: 67                    $<br/> * $Date:: 2007-08-28 21:37:07 #$<br/>
 34  
  * $Date:: 2007-08-28 21:37:07 #$<br/>
 35  
  */
 36  
 public class PropertiesManagerImpl implements IPropertiesManager
 37  
 {
 38  
     /**
 39  
      * Logger instance.
 40  
      */
 41  5
     final public static Logger LOG = Logger.getLogger(PropertiesManagerImpl.class);
 42  
 
 43  
     /**
 44  
      * The default bundle to be used.
 45  
      */
 46  
     private ResourceBundle m_defaultBundle;
 47  
 
 48  
     /**
 49  
      * The custom bundle to be used.
 50  
      */
 51  
     private ResourceBundle m_customBundle;
 52  
 
 53  
     /**
 54  
      * This variable is used for indicating the functionality was already initialized.
 55  
      */
 56  
     private static boolean isInitialized;
 57  
 
 58  
     /**
 59  
      * Please review the following Java Docs to understand the meaning of this props:
 60  
      * {@link com.sourceforge.jpatterns.core.configuration.PropertiesProvider.JPProperties.USE_ONLY_CUSTOM_FRAMEWORK_PROPERTIES}
 61  
      */
 62  
     private static boolean useOnlyCustomPropsIfPresent;
 63  
 
 64  
     /**
 65  
      * The reason this class has the constructor and implements "singleton" - we are worrying if we need interface for it later.
 66  
      */
 67  
     public PropertiesManagerImpl()
 68  
     {
 69  
         // 00: initial configuration
 70  10
         super();
 71  10
         initConfigs();
 72  10
     }
 73  
 
 74  
     /**
 75  
      * Perform the check if the functionality was initialized. Throws <code>IllegalStateException</code> in the case the functionality
 76  
      * was not intialized. Should be used for all the "state read/write" methods just to be sure all is ok.
 77  
      */
 78  
     protected void checkIsInitialized()
 79  
     {
 80  13535
         if (!isInitialized)
 81  
         {
 82  0
             throw new IllegalStateException("Please be noticed the PropertiesManagerImpl is not initialized.");
 83  
         }
 84  13535
     }
 85  
 
 86  
     /**
 87  
      * Init the resource bundles configuration (methods <code>getDefaultBundleFileName and getCustomBundleFileName</code> are used
 88  
      * for the retrieving the actual nname of the properties to be obtained during the initialization process)
 89  
      * <br/>
 90  
      * Protected to allow to cover that with the unit tests
 91  
      */
 92  
     public void initConfigs()
 93  
     {
 94  809
         isInitialized = false;
 95  
         // todo [zmicer]: clarify for what it is ???
 96  809
         if (null == m_defaultBundle && null != JPatternsPropsUtils.getDefaultBundle())
 97  
         {
 98  10
             m_defaultBundle = JPatternsPropsUtils.getDefaultBundle();
 99  10
             m_customBundle = JPatternsPropsUtils.getCustomBundle();
 100  10
             JPatternsPropsUtils.setDefaultBundle(null);
 101  10
             JPatternsPropsUtils.setCustomBundle(null);
 102  10
         }
 103  
         else
 104  
         {
 105  799
             final String defaultProps = JPatternsPropsUtils.getDefaultBundleName();
 106  799
             final String customProps = JPatternsPropsUtils.getCustomBundleName();
 107  799
             if (null == defaultProps)
 108  
             {
 109  0
                 throw new IllegalStateException("The name of default configuration can not be null.");
 110  
             }
 111  799
             m_defaultBundle = ResourceUtils.getResourceBundle(defaultProps);
 112  799
             m_customBundle = ResourceUtils.getResourceBundle(customProps);
 113  
         }
 114  
 
 115  809
         isInitialized = true;
 116  
         // 01: initialize <code>useOnlyCustomPropsIfPresent</code>
 117  809
         initUseOnlyCustomConfigIfPresent();
 118  794
     }
 119  
 
 120  
 
 121  
     /**
 122  
      * @see IPropertiesManager#customConfigPresents()
 123  
      */
 124  
     public boolean customConfigPresents()
 125  
     {
 126  2524
         checkIsInitialized();
 127  2524
         return (null != m_customBundle);
 128  
     }
 129  
 
 130  
     /**
 131  
      * @see IPropertiesManager#defaultConfigPresents()
 132  
      */
 133  
     public boolean defaultConfigPresents()
 134  
     {
 135  2469
         checkIsInitialized();
 136  2469
         return (null != m_defaultBundle);
 137  
     }
 138  
 
 139  
     /**
 140  
      * @see com.sourceforge.jpatterns.core.configuration.IPropertiesManager#useOnlyCustomConfigIfPresent()
 141  
      */
 142  
     public boolean useOnlyCustomConfigIfPresent()
 143  
     {
 144  10
         checkIsInitialized();
 145  10
         return useOnlyCustomPropsIfPresent;
 146  
     }
 147  
 
 148  
     /**
 149  
      * Initialize the useOnlyCustomPropsIfPresent field.
 150  
      */
 151  
     protected void initUseOnlyCustomConfigIfPresent()
 152  
     {
 153  814
         checkIsInitialized();
 154  814
         final String defaultValue = getDefaultBundle(PropertiesProvider.JPProperties.USE_ONLY_CUSTOM_FRAMEWORK_PROPERTIES);
 155  799
         final String customValue = getCustomBundle(PropertiesProvider.JPProperties.USE_ONLY_CUSTOM_FRAMEWORK_PROPERTIES);
 156  799
         if (null == customValue || "".equals(customValue))
 157  
         {
 158  799
             if (null == defaultValue || "".equals(defaultValue))
 159  
             {
 160  
                 // 00: the case when there are definitions with this settings at the both custom and default property files.
 161  190
                 useOnlyCustomPropsIfPresent = false;
 162  190
             }
 163  
             else
 164  
             {
 165  609
                 final Boolean boolObject = StringUtils.getBoolean(defaultValue);
 166  609
                 if (null == boolObject)
 167  
                 {
 168  0
                     throw new IllegalStateException("The property defined at the properties file doesn't take boolean value");
 169  
                 }
 170  609
                 useOnlyCustomPropsIfPresent = boolObject;
 171  
             }
 172  609
         }
 173  
         else
 174  
         {
 175  0
             final Boolean boolObject = StringUtils.getBoolean(customValue);
 176  0
             if (null == boolObject)
 177  
             {
 178  0
                 throw new IllegalStateException("The property defined at the properties file doesn't take boolean value");
 179  
             }
 180  0
             useOnlyCustomPropsIfPresent = boolObject;
 181  
         }
 182  799
     }
 183  
 
 184  
     /**
 185  
      * @see IPropertiesManager#getBundle(java.lang.String)
 186  
      */
 187  
     public String getBundle(final String key)
 188  
     {
 189  1645
         checkIsInitialized();
 190  1645
         InputArgumentUtils.checkStrings(true, key);
 191  1630
         final String customValue = getCustomBundle(key);
 192  1630
         if ((useOnlyCustomPropsIfPresent && customConfigPresents()) || null != customValue)
 193  
         {
 194  90
             return customValue;
 195  
         }
 196  1540
         return getDefaultBundle(key);
 197  
     }
 198  
 
 199  
     /**
 200  
      * @see IPropertiesManager#getBundle(Class)
 201  
      */
 202  
     public String getBundle(final Class key)
 203  
     {
 204  1150
         checkIsInitialized();
 205  1150
         if (null == key)
 206  
         {
 207  10
             throw new IllegalArgumentException("The class for each we need to get the resource bundle can not be null");
 208  
         }
 209  1140
         final String nameKey = ReflexionUtils.getBaseName(key);
 210  1140
         if (null == nameKey)
 211  
         {
 212  0
             throw new IllegalStateException("Could not get the base name using the Class instance. Please check the sources.");
 213  
         }
 214  1140
         return getBundle(nameKey);
 215  
     }
 216  
 
 217  
     /**
 218  
      * @see com.sourceforge.jpatterns.core.configuration.IPropertiesManager#getBundledObject(Class)
 219  
      */
 220  
     public Object getBundledObject(final Class key)
 221  
     {
 222  1115
         final String bundledObjectClassName = getBundle(key);
 223  1110
         if (null == bundledObjectClassName)
 224  
         {
 225  5
             throw new JPInitializationException("Can not find the name of the class instance of which we should instantiate. Class name: " +
 226  
                 key.getName());
 227  
         }
 228  
 
 229  
         // the object we got using reflexion
 230  
         try
 231  
         {
 232  1105
             final Object object= ReflexionUtils.reflectObject(bundledObjectClassName, true);
 233  1095
             if (null == object)
 234  
             {
 235  0
                 throw new JPInitializationException("Illegal, incorrect definition of the Class is defined at the properties file. " +
 236  
                     "Class name :" + key.getName() + ", value for the key is : " + bundledObjectClassName);
 237  
             }
 238  1095
             return object;
 239  
         }
 240  10
         catch(Exception ex)
 241  
         {
 242  10
             LoggingUtils.logException(LOG, ex, null, this.getClass());
 243  10
             throw new JPInitializationException(ex);
 244  
         }
 245  
 
 246  
     }
 247  
 
 248  
     /**
 249  
      * @see com.sourceforge.jpatterns.core.configuration.IPropertiesManager#getBundledObject(String)
 250  
      */
 251  
     public Object getBundledObject(final String key)
 252  
     {
 253  5
         final String bundledObjectClassName = getBundle(key);
 254  0
         if (null == bundledObjectClassName)
 255  
         {
 256  0
             throw new JPInitializationException("Can not find the name of the class instance of which we should instantiate. Class name: " +
 257  
                 key);
 258  
         }
 259  
         // the object we got using reflexion
 260  0
         final Object object = ReflexionUtils.reflectObject(bundledObjectClassName, false);
 261  0
         if (null == object)
 262  
         {
 263  0
             throw new JPInitializationException("Illegal, incorrect definition of the Class is defined at the properties file. " +
 264  
                 "Class name :" + key + ", value for the key is : " + bundledObjectClassName);
 265  
         }
 266  0
         return object;
 267  
     }
 268  
 
 269  
     /**
 270  
      * @see IPropertiesManager#getDefaultBundle(java.lang.String)
 271  
      */
 272  
     public String getDefaultBundle(final String key)
 273  
     {
 274  2419
         checkIsInitialized();
 275  2419
         InputArgumentUtils.checkStrings(true, key);
 276  2404
         if (!defaultConfigPresents())
 277  
         {
 278  15
             throw new JPInitializationException("The default configuration is not present. It is illegale state of the JPatterns " +
 279  
                 "framework.");
 280  
         }
 281  2389
         String result = null;
 282  
         try
 283  
         {
 284  2389
             result = m_defaultBundle.getString(key);
 285  2179
             if (null != result && !"".equals(result))
 286  
             {
 287  2179
                 LOG.debug("The value for the key [" + key + "] was found using the default properties.");
 288  2179
                 return result;
 289  
             }
 290  
         }
 291  210
         catch (Exception ex)
 292  
         {
 293  
             // just catching, and that is all
 294  0
         }
 295  210
         return result;
 296  
     }
 297  
 
 298  
     /**
 299  
      * @see IPropertiesManager#getCustomBundle(java.lang.String)
 300  
      */
 301  
     public String getCustomBundle(final String key)
 302  
     {
 303  2449
         checkIsInitialized();
 304  2449
         InputArgumentUtils.checkStrings(true, key);
 305  2449
         if (!customConfigPresents())
 306  
         {
 307  1784
             LOG.debug("Trying to obtain the bundle with the key " + key + " from the custom properties: the custom properties file " +
 308  
                 "is absent");
 309  1784
             return null;
 310  
         }
 311  665
         String result = null;
 312  
         try
 313  
         {
 314  665
             result = m_customBundle.getString(key);
 315  95
             if (null != result && !"".equals(result))
 316  
             {
 317  95
                 LOG.debug("The value for the key [" + key + "] was found using the custom properties.");
 318  95
                 return result;
 319  
             }
 320  
         }
 321  570
         catch (Exception ex)
 322  
         {
 323  
             // just catching, and that is all
 324  0
         }
 325  570
         return result;
 326  
     }
 327  
 
 328  
     /**
 329  
      * @return the Enumeration of the keys (merged one or the custom one or the default one - it depends on the following:
 330  
      * a. if custom properties files is present or was specified at the JVM parameter b. study the
 331  
      * <code>com.sourceforge.jpatterns.core.configuration.PropertiesProvider.JPProperties.USE_ONLY_CUSTOM_FRAMEWORK_PROPERTIES</code>)
 332  
      * todo: [zmicer] think over the caching these values between the initialization periods - just to increase the performance of the
 333  
      * framework initialization!
 334  
      */
 335  
     public Set<String> getMergedKeys()
 336  
     {
 337  50
         checkIsInitialized();
 338  50
         Set<String> customSet = new HashSet<String>();
 339  50
         if (customConfigPresents())
 340  
         {
 341  5
             final Enumeration<String> customEnum = m_customBundle.getKeys();
 342  5
             customSet = CollectionsUtils.toSet(customEnum);
 343  5
             if (useOnlyCustomPropsIfPresent && customConfigPresents())
 344  
             {
 345  0
                 return customSet;
 346  
             }
 347  
         }
 348  50
         Set<String> defaultSet = new HashSet<String>();
 349  50
         if (defaultConfigPresents())
 350  
         {
 351  50
             final Enumeration<String> defaultEnum = m_defaultBundle.getKeys();
 352  50
             defaultSet = CollectionsUtils.toSet(defaultEnum);
 353  50
             if (null != customSet && !customSet.isEmpty())
 354  
             {
 355  5
                 defaultSet.addAll(customSet);
 356  
             }
 357  
         }
 358  50
         if (defaultSet.isEmpty())
 359  
         {
 360  0
             return customSet;
 361  
         }
 362  
 
 363  50
         return defaultSet;
 364  
     }
 365  
 }