Coverage Report - org.naftulin.configmgr.ConfigurationManagementImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
ConfigurationManagementImpl
85%
45/53
79%
11/14
0
ConfigurationManagementImpl$1
N/A
N/A
0
ConfigurationManagementImpl$ConfigurationManagerImpl
95%
20/21
80%
8/10
0
 
 1  
 package org.naftulin.configmgr;
 2  
 
 3  
 import java.util.Collections;
 4  
 import java.util.HashMap;
 5  
 import java.util.Iterator;
 6  
 import java.util.LinkedList;
 7  
 import java.util.List;
 8  
 import java.util.Map;
 9  
 import java.util.Set;
 10  
 import java.util.Map.Entry;
 11  
 
 12  
 import org.apache.log4j.Logger;
 13  
 import org.naftulin.configmgr.parsers.ConfigurationRecordsToEntriesConverter;
 14  
 
 15  
 /**
 16  
  * Configuration Management provides a convinient way to manage configuration for your programs.
 17  
  * Alows to load and reload configurations, add configuration, list all the configurations and
 18  
  * returns configuration manager interface. Configuration manager interface returns configuration
 19  
  * based on the key.
 20  
  *  
 21  
  * @author Henry Naftulin
 22  
  * @since 1.0
 23  
  */
 24  5
 public class ConfigurationManagementImpl implements ConfigurationManagement {
 25  220
         private final class ConfigurationManagerImpl implements ConfigurationManager {
 26  
                 /**
 27  
                  * Returns the configuration based on the key. 
 28  
                  * If the configuration is not found or is in error state throws an exception.
 29  
                  * @param key configuration mapped under.
 30  
                  * @return the configuration based on the key.
 31  
                  * @throws ConfigurationManagerException if configuration is not found or in error state.
 32  
                  */
 33  
                 public Object getConfiguration(final String key) throws ConfigurationManagerException {
 34  
                         ConfigurationManagementEntry entry;
 35  85
                         synchronized (lock) {
 36  75
                                 if (configuration.containsKey(key)) {
 37  65
                                         entry = configuration.get(key);
 38  65
                                         if (! entry.isError()) {
 39  65
                                                 return entry.getContent();
 40  
                                         }
 41  0
                                         throw new ConfigurationManagerException("Entry was found, but it is in error state. " + entry.getContent());
 42  
                                 }                                        
 43  
                         }
 44  10
                         log.warn("no entry for " + key + " is found in the configuration manager");
 45  10
                         throw new EntryNotFoundException("no entry for " + key + " is found.");
 46  
                 }
 47  
 
 48  
                 /**
 49  
                  * Returns the configuration based on the key if found and not in error state. Otherwise
 50  
                  * returns null.
 51  
                  * @param key configuration mapped under.
 52  
                  * @return conifguration if found and it does not countain errors, null otherwise
 53  
                  */
 54  
                 public Object getConfigurationSilent(final String key) {
 55  115
                         boolean entryFound = false;
 56  115
                         ConfigurationManagementEntry entry = null;
 57  115
                         Object retObject = null;
 58  
                         // minimal syncronized block
 59  230
                         synchronized (lock) {
 60  115
                                 entryFound = configuration.containsKey(key);
 61  115
                                 if (entryFound) {
 62  110
                                         entry = configuration.get(key);
 63  110
                                         if (!entry.isError()) {
 64  110
                                                 retObject = entry.getContent();
 65  
                                         }
 66  
                                 }
 67  
                         }
 68  
 
 69  115
                         if (!entryFound) {
 70  5
                                 log.warn("no entry for " + key + " is found in the configuration manager");
 71  
                         }
 72  115
                         return retObject;
 73  
                 }
 74  
 
 75  
                 
 76  
         }
 77  
 
 78  20
         private static final Logger log = Logger.getLogger(ConfigurationManagementImpl.class);
 79  
 
 80  
         /**
 81  
          * Anonymous private class that represents configuration manager interface.
 82  
          */
 83  
         private final ConfigurationManager manager;
 84  190
         private final Object lock;
 85  
         private String masterRecordFileName;
 86  475
         private Map<String, ConfigurationManagementEntry> configuration = new HashMap<String, ConfigurationManagementEntry>();
 87  
         private boolean intialized;
 88  
         
 89  
         
 90  
         /**
 91  
          * Creates a configuration manager without any configurations. Needed only for the unit testing.
 92  
          */
 93  110
         ConfigurationManagementImpl() {
 94  110
                 lock = new Object();
 95  110
                 manager = new ConfigurationManagerImpl();
 96  110
         }
 97  
 
 98  
         /**
 99  
          * Creates a configuration management engine given a master configuration file.
 100  
          * @param masterRecordFileName a file that describes configuration for configuration manager
 101  
          * @throws ConfigurationManagerException if master configuration file cannot be read or contains an error.
 102  
          */
 103  
         ConfigurationManagementImpl(String masterRecordFileName) throws ConfigurationManagerException {
 104  80
                 this();
 105  80
                 this.masterRecordFileName = masterRecordFileName;
 106  
                 //no reload necessary here, it is done on the factory level. More flexibe that way, which is
 107  
                 //if we were to create configuration manager we can control when to load the configurations...reload();
 108  80
         }
 109  
         
 110  
         /**
 111  
          * Reloades configurations stored in the configuration management engine. The
 112  
          * configurations are read again, parsed and stored.
 113  
          * @throws ConfigurationManagerException if a problem occurs while reading or parsing the configurations.
 114  
          */
 115  
         public void reload() throws ConfigurationManagerException {
 116  85
                 final Map<String, ConfigurationManagementEntry> newConfig = readConfiguration();
 117  170
                 synchronized (lock) {
 118  85
                         this.configuration = newConfig;
 119  85
                         this.intialized = true;
 120  
                 }
 121  
 
 122  85
         }
 123  
 
 124  
         /**
 125  
          * Returns {@link ConfigurationManagementEntry configuration management entry} based on the key passed.
 126  
          * @param key key the entry is stored under
 127  
          * @return configuration management entry based on the key passed
 128  
          * @throws ConfigurationManagerException if the entry is not found.
 129  
          */
 130  
         public ConfigurationManagementEntry getConfigurationManagmentEntry(final String key) throws ConfigurationManagerException {
 131  0
                 boolean entryFound = false;
 132  0
                 ConfigurationManagementEntry entry = null;
 133  0
                 synchronized (lock) {
 134  0
                         entryFound = configuration.containsKey(key);
 135  0
                         entry = configuration.get(key);
 136  
                 }
 137  0
                 if (!entryFound) {
 138  0
                         throw new EntryNotFoundException("Entry identified by key "+ key + " was not found");
 139  
                 }
 140  0
                 return entry;
 141  
         }
 142  
 
 143  
         /**
 144  
          * Returns a list of {@link ConfigurationManagementEntry configuration management entries} managed by this configuration managment engine.
 145  
          * @return a list of {@link ConfigurationManagementEntry configuration management entries} managed by this configuration managment engine.
 146  
          */
 147  
         public List<ConfigurationManagementEntry> getConfigurationManagmentEntries() {
 148  15
                 final List<ConfigurationManagementEntry> entries = new LinkedList<ConfigurationManagementEntry>();
 149  15
                 Set<Entry<String, ConfigurationManagementEntry>> set = null;
 150  30
                 synchronized (lock) {
 151  15
                         set = Collections.unmodifiableSet(this.configuration.entrySet());
 152  
                 }
 153  15
                 if (set != null) {
 154  15
                         Iterator<Entry<String, ConfigurationManagementEntry>> it = set.iterator();
 155  45
                         while(it.hasNext()) {
 156  15
                                 Entry<String, ConfigurationManagementEntry> mapEntry = it.next();
 157  15
                                 entries.add((ConfigurationManagementEntry) mapEntry.getValue());
 158  
                         }
 159  
                 }
 160  15
                 return Collections.unmodifiableList(entries);
 161  
         }
 162  
 
 163  
         /**
 164  
          * Returns true if configuration Management has loaded configurations. Returns false
 165  
          * before that point. After instantiation, we can confgure where configuration master
 166  
          * record is read from. Once the master record is configured, we will be able to reload
 167  
          * configuration manager. Reloading configuration manager will load all configurations,
 168  
          * and the flag will switch to initialized.  
 169  
          * @return true if configuration Management has loaded configurations.        
 170  
          */
 171  
         public boolean isInitialized() {                
 172  10
                 synchronized (lock) {
 173  10
                         return intialized;
 174  
                 }                
 175  
         }
 176  
         
 177  
         /**
 178  
          * Returns a map with {@link ConfigurationManagementEntry configuration management entries} keyed by confguration entry key. 
 179  
          * Reads and parses all configuration entries described in master confiuration file.
 180  
          * @return  a map with {@link ConfigurationManagementEntry configuration management entries} keyed by confguration entry key. 
 181  
          * @throws ConfigurationManagerException if a configuration cannot be read or parsed.
 182  
          */
 183  
         private Map<String, ConfigurationManagementEntry> readConfiguration() throws ConfigurationManagerException {
 184  85
                 final Map<String, ConfigurationManagementEntry> newConfiguration = new HashMap<String, ConfigurationManagementEntry>();
 185  85
                 if (masterRecordFileName != null) {
 186  80
                         final ConfigurationRecordsToEntriesConverter converter = new ConfigurationRecordsToEntriesConverter();
 187  80
                         final ConfigurationManagementEntry[] entries = converter.createConfigurationEntriesFromConfigurationFile(masterRecordFileName);
 188  400
                         for(int i=0; i < entries.length; ++i) {
 189  320
                                 addConfigurationManagmentEntry(newConfiguration, entries[i]);
 190  
                         }
 191  
                 }
 192  85
                 return newConfiguration;
 193  
         }
 194  
 
 195  
         /**
 196  
          * Returns configuration manager created by the configuration management engine.
 197  
          * @return configuration manager.
 198  
          */
 199  
         public ConfigurationManager getConfigurationManager() {
 200  90
                 synchronized(lock) {
 201  90
                         return this.manager;
 202  
                 }
 203  
         }
 204  
 
 205  
         /**
 206  
          * Adds a configuration entry to the configuration manager. Needed to add ad-hoc
 207  
          * configurations to the configuration manager. when adding a new configuration with the same key
 208  
          * old configuration should be replaced. Is overwritten flag for the new 
 209  
          * configuration should be set. Delegates to private method that takes
 210  
          * a map to which the configuration is added.
 211  
          * @param entry configuration entry
 212  
          * @exception if the entry is in error 
 213  
          */
 214  
         public void addConfigurationManagmentEntry(final ConfigurationManagementEntry entry) throws EntryInErrorException {
 215  60
                 addConfigurationManagmentEntry(this.configuration, entry);
 216  55
         }
 217  
         
 218  
         /**
 219  
          * Adds a configuration entry to the configuration manager. Needed to add ad-hoc
 220  
          * configurations to the configuration manager. when adding a new configuration with the same key
 221  
          * old configuration should be replaced. Is overwritten flag for the new 
 222  
          * configuration should be set. 
 223  
          * @param toConfiguration a configuration to which an entry is added
 224  
          * @param entry configuration entry
 225  
          * @exception if the entry is in error 
 226  
          */
 227  
         private void addConfigurationManagmentEntry(final Map<String, ConfigurationManagementEntry> toConfiguration, 
 228  
                         final ConfigurationManagementEntry entry) throws EntryInErrorException {
 229  380
                 if (entry.getKey() == null) {
 230  5
                         throw new EntryInErrorException("Entry key should not be null. Entry is " + entry);
 231  
                 }
 232  750
                 synchronized(lock) {
 233  375
                         final Object obj = toConfiguration.put(entry.getKey(), entry);
 234  375
                         entry.setOverwritten(obj != null);
 235  
                 }
 236  375
         }
 237  
 }