Coverage Report - com.sourceforge.jpatterns.core.configuration.PropertiesProvider
 
Classes in this File Line Coverage Branch Coverage Complexity
PropertiesProvider
90% 
100% 
0
 
 1  
 package com.sourceforge.jpatterns.core.configuration;
 2  
 
 3  
 import com.sourceforge.jpatterns.core.configuration.exceptions.JPInitializationException;
 4  
 import com.zmicer.utils.InputArgumentUtils;
 5  
 import com.zmicer.utils.StringUtils;
 6  
 import org.apache.log4j.Logger;
 7  
 
 8  
 import java.util.HashMap;
 9  
 import java.util.Map;
 10  
 import java.util.Set;
 11  
 
 12  
 /**
 13  
  * This class would store the properties per the key. The values are defined at the properties file of the JPatterns.
 14  
  * <br/>
 15  
  * The storage would be the Map, the initialization of the properties would be performed at this class (method #init).
 16  
  * <br/>
 17  
  * Please remember that the priority has custom properties files
 18  
  * ({@link com.sourceforge.jpatterns.core.configuration.PropertiesManagerImpl#m_customBundle}),
 19  
  * and then the default bundle is asked to provide the property:
 20  
  * ({@link com.sourceforge.jpatterns.core.configuration.PropertiesManagerImpl#m_defaultBundle}).
 21  
  * <br/>
 22  
  * Please review properly the following Java Docs - it is important for understanding of the algorithm of working of the JPatterns
 23  
  * configuration functionality.
 24  
  * {@link com.sourceforge.jpatterns.core.configuration.PropertiesProvider.JPProperties.USE_ONLY_CUSTOM_FRAMEWORK_PROPERTIES}
 25  
  *
 26  
  * todo: [zmicer] think over the moving this functionality to the common utility/framework.
 27  
  * <br/>
 28  
  * <strong>Also important feature in the behaviour of this class is: it won't store the keys/values which define the implementations of the
 29  
  * interfaces/abstract classes. It is done in the following way. We would check the values of the properties trying to instantiate the
 30  
  * appropriate classes instances. If it is done succesfully - we would exclude such values.</strong>
 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 PropertiesProvider
 37  
 {
 38  
     /**
 39  
      * Logger instance.
 40  
      */
 41  5
     final public static Logger LOG = Logger.getLogger(PropertiesProvider.class);
 42  
 
 43  
     /**
 44  
      * The singleton instance of the property provider.
 45  
      */
 46  5
     final private static PropertiesProvider PROVIDER = new PropertiesProvider();
 47  
 
 48  
     /**
 49  
      * Signs of the initialization took place.
 50  
      */
 51  5
     private boolean m_isInitialized = false;
 52  
 
 53  
     /**
 54  
      * This map stores all the important properties we need (which values are the <code>Boolean</code> objects).
 55  
      */
 56  5
     private Map<String, Boolean> m_booleanProperties = new HashMap<String, Boolean>();
 57  
 
 58  
     /**
 59  
      * This map stores all the important properties we need (which values are the <code>String</code> objects).
 60  
      */
 61  5
     private Map<String, String> m_stringProperties = new HashMap<String, String>();
 62  
 
 63  
     /**
 64  
      * This interface stores the keys for necessary and important for the JPatterns properties.
 65  
      * <br/>
 66  
      * Please extend this interface with the values you would add to the properties files (default one). In the case new properties would
 67  
      * be added to the custom framework properties - create your own interface somewhere else.
 68  
      */
 69  
     public interface JPProperties
 70  
     {
 71  
         /**
 72  
          * If the custom properties would be found only its value would be used. Please be noticed that this property is very important
 73  
          * as defines the behaviour of all the configuration sub-system. The following rule takes power with it. This property is seached
 74  
          * at the both default and custom properties, the custom has the priority. The further loading of the props is done using its
 75  
          * value.
 76  
          * <br/>
 77  
          * If both the properties files do not specify this property - we would use the custom ones if custom file presents and has these
 78  
          * properties, otherwise the default values would be used.
 79  
          */
 80  
         String USE_ONLY_CUSTOM_FRAMEWORK_PROPERTIES = "jpatterns.configuration.props.use.only.custom.if.present";
 81  
 
 82  
         /**
 83  
          * this settings in the case its value is true defines that *custom* *framework* configuration would override all the *default*
 84  
          * *framework* configuration (it won't be used at all) in the case this is false - when merging default and custom settings firstly
 85  
          * default would be written to the result, and then all the settings from custom would override default one.
 86  
          */
 87  
         String USE_ONLY_CUSTOM_FRAMEWORK_XML = "jpatterns.configuration.xml.use.only.custom.framework.settings.if.present";
 88  
 
 89  
         /**
 90  
          * this settings in the case its value is true defines that *custom* *consumer* configuration would override all the *default*
 91  
          * *consumer* configuration (it won't be used at all) in the case this is false - when merging default and custom settings firstly
 92  
          * default would be written to the result, and then all the settings from custom would override default one.
 93  
          * a. default consumer settings - appropriate xml files were found at the classpath and all the dirs of the classpath
 94  
          * b. custom consumer configuration was provided by the properties framework configuration (it also could be provided as JVM
 95  
          * parameter, in this case JVM value would have the sense of custom consumer config).
 96  
          */
 97  
         String USE_ONLY_CUSTOM_CONSUMER_XML = "jpatterns.configuration.xml.use.only.custom.consumer.settings.if.present";
 98  
 
 99  
         /**
 100  
          * Defines the depth for the validating/overriding the JPatterns configuration.
 101  
          * <br/>
 102  
          * the default value is
 103  
          * <code>com.sourceforge.jpatterns.core.configuration.PropertiesProvider.OverridingDepths.OVERRIDING_LEVEL_SECTION</code>
 104  
          *
 105  
          */
 106  
         String XML_CONFIG_OVERRIDING_DEPTH = "jpatterns.configuration.xml.overriding.depth";
 107  
 
 108  
         /**
 109  
          * <code>XML_CONFIG_CUSTOM_OVERRIDES_NOT_DEPENDING_ON_PRIORITY</code>
 110  
          * <br/>
 111  
          * Default value is <code>false</code>
 112  
          */
 113  
         String XML_CONFIG_CUSTOM_OVERRIDES_NOT_DEPENDING_ON_PRIORITY = 
 114  
             "jpatterns.configuration.xml.custom.overrides.not.depending.on.priorities";
 115  
     }
 116  
 
 117  
     /**
 118  
      * This enum defines the depths we could use for the defining the overriding types.
 119  
      * <br/>
 120  
      * Consider the idea of the common stuff for the converting possible types of the properties files to the enum (check how it is done
 121  
      * fore the castor - may be it is worth to use castor for it) - idea of <strong>Prosper</strong>!!!
 122  
      * <br/>
 123  
      * Please review the comments to the <strong>jpatterns.configuration.xml.overriding.depth</strong> property in the
 124  
      * <strong>jpatterns.properties</strong> properties file.
 125  
      */
 126  15
     public enum OverridingDepths
 127  
     {
 128  
         /**
 129  
          * Says that it is incorrect case when the sections contains two section with identical pathes (scopes, section names, priorities).
 130  
          */
 131  5
         OVERRIDING_LEVEL_SECTION,
 132  
         /**
 133  
          * Says it is correct case of existence of two section objects with identical path (scope, section name, priorities) - just because
 134  
          * it is allowed to extend the existed sections items configuration by the additional items.
 135  
          */
 136  5
         OVERRIDING_LEVEL_ITEM
 137  
     }
 138  
 
 139  
     /**
 140  
      * Default public constructor
 141  
      * <br/>
 142  
      * Please be carefull in adding some initialization functionality at this constructor - this is singleton, and the call of the
 143  
      * constructor is done at the static initialization level.
 144  
      */
 145  
     private PropertiesProvider()
 146  
     {
 147  5
         super();
 148  5
     }
 149  
 
 150  
     /**
 151  
      * Init method - initializes the provided.
 152  
      * todo [zmicer]: think over the adjustment here!!! we should initialize the objects just to check they are working
 153  
      * 
 154  
      *
 155  
      * @param manager the manager, entry point to the properties values.
 156  
      *                Can not be null (otherwise <code>IllegalArgumentException</code> would appear).
 157  
      */
 158  
     protected void init(final IPropertiesManager manager)
 159  
     {
 160  40
         PROVIDER.m_isInitialized = false; //[Silent.codeChangies] value changed from true to false.
 161  40
         if (null == manager)
 162  
         {
 163  0
             throw new IllegalArgumentException("IPropertiesManager can not be null.");
 164  
         }
 165  40
         final Set<String> mergedKeys = manager.getMergedKeys();
 166  40
         if (null == mergedKeys || mergedKeys.isEmpty())
 167  
         {
 168  0
             throw new JPInitializationException("The properties manager doesn't contain the bundles at all.");
 169  
         }
 170  40
         for (final String key : mergedKeys)
 171  
         {
 172  400
             final String value = manager.getBundle(key);
 173  400
             final Boolean boolValue = StringUtils.getBoolean(value);
 174  400
             if ((key.contains("I") && value.contains(key.substring(1)) && value.contains(".")))
 175  
             {
 176  165
                 continue;
 177  
             }
 178  235
             if (null != boolValue)
 179  
             {
 180  125
                 m_booleanProperties.put(key, boolValue);
 181  125
             }
 182  
             else
 183  
             {
 184  110
                 m_stringProperties.put(key, value);
 185  
             }
 186  235
         }
 187  40
         PROVIDER.m_isInitialized = true;
 188  40
     }
 189  
 
 190  
     /**
 191  
      * Get instance of the PropertiesProvider.
 192  
      * todo: [zmicer] seems to be not the best way (because IPropertiesProvider is passed.)
 193  
      *
 194  
      * @param manager      is necessary for the initializing properties values (if they are initialized already - it is just skipped.)
 195  
      *                     Can not be null (otherwise <code>IllegalArgumentException</code> would appear).
 196  
      * @param reloadAnyWay says to reload the properties anyway. It could be used at the unit tests. In the normal life - it should
 197  
      *                     be set to false;
 198  
      *
 199  
      * @return the PropertiesProvider instance.
 200  
      */
 201  
     public static PropertiesProvider getInstance(final IPropertiesManager manager, final boolean reloadAnyWay)
 202  
     {
 203  1162
         if (null == manager)
 204  
         {
 205  0
             throw new IllegalArgumentException("IPropertiesManager can not be null.");
 206  
         }
 207  1162
         if (!PROVIDER.m_isInitialized || reloadAnyWay)
 208  
         {
 209  35
             PROVIDER.init(manager);
 210  
         }
 211  1162
         return PROVIDER;
 212  
     }
 213  
 
 214  
     /**
 215  
      * @param key The key to retrieve the appropriate value. Can not be null (otherwise <code>IllegalArgumentException</code> would appear).
 216  
      *            Please use the values of JPProperties (surely having the boolean sense).
 217  
      *
 218  
      * @return the boolean property.
 219  
      */
 220  
     public Boolean getBooleanProperty(final String key)
 221  
     {
 222  1339
         InputArgumentUtils.checkStrings(true, key);
 223  1329
         checkIfInitialized();
 224  1329
         return m_booleanProperties.get(key);
 225  
     }
 226  
 
 227  
     /**
 228  
      * @param key The key to retrieve the appropriate value. Can not be null (otherwise <code>IllegalArgumentException</code> would appear).
 229  
      *            Please use the values of JPProperties (surely having the boolean sense).
 230  
      *
 231  
      * @return the String property.
 232  
      */
 233  
     public String getStringProperty(final String key)
 234  
     {
 235  1030
         InputArgumentUtils.checkStrings(true, key);
 236  1020
         checkIfInitialized();
 237  1020
         return m_stringProperties.get(key);
 238  
     }
 239  
 
 240  
     /**
 241  
      * Check if the <code>PropertiesProvider</code> was iinitialized.
 242  
      */
 243  
     protected void checkIfInitialized()
 244  
     {
 245  2354
         if (!m_isInitialized)
 246  
         {
 247  0
             throw new IllegalStateException("The propertis provider was not initialized.");
 248  
         }
 249  2354
     }
 250  
 }