Clover coverage report - Maven Clover report
Coverage timestamp: Mon Sep 3 2007 08:24:07 EEST
file stats: LOC: 250   Methods: 6
NCLOC: 96   Classes: 3
 
 Source file Conditionals Statements Methods TOTAL
PropertiesProvider.java 71.4% 86.2% 100% 83.7%
coverage coverage
 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    final public static Logger LOG = Logger.getLogger(PropertiesProvider.class);
 42   
 43    /**
 44    * The singleton instance of the property provider.
 45    */
 46    final private static PropertiesProvider PROVIDER = new PropertiesProvider();
 47   
 48    /**
 49    * Signs of the initialization took place.
 50    */
 51    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    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    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    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    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    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  1 private PropertiesProvider()
 146    {
 147  1 super();
 148    }
 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  8 protected void init(final IPropertiesManager manager)
 159    {
 160  8 PROVIDER.m_isInitialized = false; //[Silent.codeChangies] value changed from true to false.
 161  8 if (null == manager)
 162    {
 163  0 throw new IllegalArgumentException("IPropertiesManager can not be null.");
 164    }
 165  8 final Set<String> mergedKeys = manager.getMergedKeys();
 166  8 if (null == mergedKeys || mergedKeys.isEmpty())
 167    {
 168  0 throw new JPInitializationException("The properties manager doesn't contain the bundles at all.");
 169    }
 170  8 for (final String key : mergedKeys)
 171    {
 172  80 final String value = manager.getBundle(key);
 173  80 final Boolean boolValue = StringUtils.getBoolean(value);
 174  80 if ((key.contains("I") && value.contains(key.substring(1)) && value.contains(".")))
 175    {
 176  33 continue;
 177    }
 178  47 if (null != boolValue)
 179    {
 180  25 m_booleanProperties.put(key, boolValue);
 181    }
 182    else
 183    {
 184  22 m_stringProperties.put(key, value);
 185    }
 186    }
 187  8 PROVIDER.m_isInitialized = true;
 188    }
 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  242 public static PropertiesProvider getInstance(final IPropertiesManager manager, final boolean reloadAnyWay)
 202    {
 203  242 if (null == manager)
 204    {
 205  0 throw new IllegalArgumentException("IPropertiesManager can not be null.");
 206    }
 207  242 if (!PROVIDER.m_isInitialized || reloadAnyWay)
 208    {
 209  7 PROVIDER.init(manager);
 210    }
 211  242 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  279 public Boolean getBooleanProperty(final String key)
 221    {
 222  279 InputArgumentUtils.checkStrings(true, key);
 223  277 checkIfInitialized();
 224  277 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  214 public String getStringProperty(final String key)
 234    {
 235  214 InputArgumentUtils.checkStrings(true, key);
 236  212 checkIfInitialized();
 237  212 return m_stringProperties.get(key);
 238    }
 239   
 240    /**
 241    * Check if the <code>PropertiesProvider</code> was iinitialized.
 242    */
 243  490 protected void checkIfInitialized()
 244    {
 245  490 if (!m_isInitialized)
 246    {
 247  0 throw new IllegalStateException("The propertis provider was not initialized.");
 248    }
 249    }
 250    }