Coverage Report - org.naftulin.configmgr.parsers.MasterRecordParser
 
Classes in this File Line Coverage Branch Coverage Complexity
MasterRecordParser
82%
62/76
67%
16/24
4.125
 
 1  
 package org.naftulin.configmgr.parsers;
 2  
 
 3  
 import java.io.BufferedInputStream;
 4  
 import java.io.BufferedReader;
 5  
 import java.io.IOException;
 6  
 import java.io.InputStream;
 7  
 import java.io.InputStreamReader;
 8  
 import java.io.Reader;
 9  
 import java.io.StringReader;
 10  
 import java.net.URL;
 11  
 import java.util.HashMap;
 12  
 import java.util.Map;
 13  
 import java.util.regex.Matcher;
 14  
 import java.util.regex.Pattern;
 15  
 
 16  
 import org.apache.commons.digester.Digester;
 17  
 import org.apache.commons.digester.xmlrules.DigesterLoader;
 18  
 import org.apache.commons.lang.StringUtils;
 19  
 import org.apache.log4j.Logger;
 20  
 import org.naftulin.configmgr.ConfigurationManagementEntry;
 21  
 import org.naftulin.configmgr.ConfigurationManagementEntryImpl;
 22  
 import org.naftulin.configmgr.ConfigurationManagerException;
 23  
 import org.naftulin.configmgr.ConfigurationType;
 24  
 import org.naftulin.configmgr.content.MasterRecordImpl;
 25  
 import org.xml.sax.SAXException;
 26  
 
 27  
 /**
 28  
  * Parses master configuration file to create a configuration entry.
 29  
  * 
 30  
  * @author Henry Naftulin
 31  
  * @version 1.0
 32  
  */
 33  70
 public class MasterRecordParser extends AbstractConfigEntryParser {
 34  
         private static final long serialVersionUID = 1L;
 35  
         private static final String MASTER_RECORD_RULES_XML = "master-record-rules.xml";
 36  5
         private static final Logger log = Logger.getLogger(MasterRecordParser.class);
 37  
         
 38  
         /**
 39  
          * Retrurns a configuration managment entry by reading the master record file passed in, and storing it's content.
 40  
          * @param key the key configuration entry will be assigned
 41  
          * @param fileUrl the file URL to be parsed.
 42  
          * @return a configuration managment with content of master configuration file.
 43  
          * @throws ConfigurationManagerException if an error occurs while parsing an entry.
 44  
          */
 45  
         public ConfigurationManagementEntry getConfigurationManagementEntry(final String key, 
 46  
                         final URL fileUrl) throws ConfigurationManagerException {
 47  85
                 validateParameters(key, fileUrl);
 48  
                 
 49  85
                 final String fileName = fileUrl.getFile();
 50  85
                 String content = null;
 51  85
                 ConfigurationManagementEntry entry = null;
 52  
                 try {
 53  85
                         final InputStream stream = fileUrl.openStream();
 54  85
                         log.debug("reading master record configuration from file " + fileName);
 55  85
                         content = readStreamContentAsString(stream);
 56  85
                         log.debug("master record configuration is " + content);
 57  
                         
 58  0
                 } catch (IOException e) {
 59  0
                         log.warn("Error while reading log4j file", e);
 60  0
                         throw new ConfigurationManagerException("Error while reading log4j file",e);
 61  
                 }                
 62  85
                 entry = new ConfigurationManagementEntryImpl(key, fileName , content, this, ConfigurationType.MASTER_RECORD);
 63  85
                 log.info("configured entry " + entry);                
 64  85
                 return entry;
 65  
         }
 66  
 
 67  
         private void validateParameters(final String key, final URL fileUrl)
 68  
                         throws ConfigurationManagerException {
 69  85
                 if (fileUrl == null) {
 70  0
                         throw new ConfigurationManagerException("file URL is null");
 71  
                 }
 72  85
                 if (fileUrl.getFile() == null) {
 73  0
                         throw new ConfigurationManagerException("file name passed in the URL " + fileUrl + " is null");
 74  
                 }
 75  85
                 if (key == null) { 
 76  0
                         throw new ConfigurationManagerException("key is null");
 77  
                 }
 78  85
         }
 79  
         
 80  
         /**
 81  
          * Returns a string representation of this parser.
 82  
          * @return a string representation of this parser.
 83  
          */
 84  
         public String toString() {
 85  255
                 return "master record parser";
 86  
         }
 87  
 
 88  
         /**
 89  
          * Returns master record based on the configuration file passed in. Parses the passed in file based
 90  
          * on the digester rules defined in MASTER_RECORD_RULES_XML and
 91  
          * uses commons digester to create master record object based on it.
 92  
          * @param fileName xml file that describe the configuration.
 93  
          * @return master record.
 94  
          * @exception ConfigurationManagerException if a master record cannot be parsed.
 95  
          */
 96  
         public MasterRecordImpl digestMasterRecord(final String fileName) throws ConfigurationManagerException{
 97  85
                 MasterRecordImpl masterRecord = null;
 98  85
                 final Digester masterRecordDigester = getDigester();
 99  85
                 if (masterRecordDigester == null) {
 100  0
                         throw new ConfigurationManagerException("Major error: could not create a digester from  " + MASTER_RECORD_RULES_XML + " file with rules to parse master record. Make sure all jars that configuration manager depends on are present.");
 101  
                 }
 102  85
                 log.debug("loaded rules to read master record");
 103  
                 //masterRecordDigester.push(masterRecord);
 104  
                 try {
 105  85
                         log.debug("loading master record file " + fileName);
 106  85
                         final URL masterRecordXml = MasterRecordParser.class.getClassLoader().getResource(fileName);
 107  85
                         if (masterRecordXml == null) {
 108  0
                                 throw new ConfigurationManagerException("Could not read master record from file " + fileName + ". Please check whether this file exists and you have read permissions to read it."); 
 109  
                         }
 110  
                         
 111  85
                         final Reader preprocessedStream = preprocessConfigurationFile(masterRecordXml);
 112  
                         
 113  85
                         masterRecord = (MasterRecordImpl) masterRecordDigester.parse(preprocessedStream);
 114  85
                         if (masterRecord == null) {
 115  0
                                 throw new ConfigurationManagerException("Could not parse master record from file " + fileName + " based on rules file " + MASTER_RECORD_RULES_XML + ". Master record is null. Please check these files to make sure they are valid");
 116  
                         }
 117  85
                         masterRecord.setFileName(fileName);
 118  0
                 } catch (IOException e) {
 119  0
                         throw new ConfigurationManagerException("Could not read master record from file " + fileName + " and rules file " + MASTER_RECORD_RULES_XML + ". Please check whether these files exist and you have read permissions to read them.", e);
 120  0
                 } catch (SAXException e) {
 121  0
                         throw new ConfigurationManagerException("Could not parse master record from file " + fileName + " and rules file " + MASTER_RECORD_RULES_XML + ". Please check whether these files are valid xml files.", e);
 122  
                 }
 123  85
                 log.info("master record parsed " + masterRecord);
 124  85
                 return masterRecord;
 125  
         }
 126  
 
 127  
         private Reader preprocessConfigurationFile(final URL masterRecordXml) throws IOException {
 128  85
                 final BufferedReader readStream = new BufferedReader(new InputStreamReader(masterRecordXml.openStream()));
 129  85
                 final StringBuffer sb = new StringBuffer();
 130  
                 String line;
 131  1830
                 while((line=readStream.readLine()) != null) {
 132  1660
                         sb.append(line);
 133  
                 }
 134  
                 
 135  85
                 final String fileContent = sb.toString();
 136  85
                 final String modifiedFileContent = doSubstitutions(fileContent);
 137  
                 
 138  85
                 final Reader preprocessedFile = new StringReader(modifiedFileContent);
 139  85
                 return preprocessedFile;
 140  
         }
 141  
 
 142  
         String doSubstitutions(final String fileContent) {
 143  110
                 String modifiedFileContent = fileContent;
 144  
                 
 145  110
                 final Pattern environmentVarPattern = Pattern.compile("\\?\\S+\\?");
 146  110
                 final Matcher environmentVarMatcher = environmentVarPattern.matcher(fileContent);
 147  
                 //Map<String, String> environmentVarValue= new HashMap<String, String>();
 148  110
                 String environmentVar = null;
 149  110
                 String value = null;
 150  230
                 while(environmentVarMatcher.find()) {
 151  10
                         String environmentVarWithMarkers = environmentVarMatcher.group();
 152  10
                         if (environmentVarWithMarkers.length()>2) {
 153  10
                                 environmentVar = environmentVarWithMarkers.substring(1, environmentVarWithMarkers.length()-1);
 154  10
                                 value = getEnvironmentVarValue(environmentVar);
 155  10
                                 modifiedFileContent = StringUtils.replace(modifiedFileContent, environmentVarWithMarkers, value);                                
 156  
                         }
 157  
                 }
 158  110
                 return modifiedFileContent;
 159  
         }
 160  
 
 161  
         String getEnvironmentVarValue(final String environmentVar) {
 162  35
                 String value = System.getProperty(environmentVar);
 163  
                 
 164  35
                 if (value == null) {
 165  25
                         value = System.getenv(environmentVar);
 166  
                 }
 167  
                 
 168  35
                 if (value == null) {
 169  5
                         value = "";
 170  
                 }
 171  35
                 return value;
 172  
         }
 173  
 
 174  
         public Digester getDigester() throws ConfigurationManagerException {
 175  125
                 URL rules = MasterRecordParser.class.getResource(MASTER_RECORD_RULES_XML);
 176  125
                 if (rules == null) {
 177  0
                         throw new ConfigurationManagerException("Major error: could not find " + MASTER_RECORD_RULES_XML + " file with rules to parse master record. Please get a configuration manager distribution.");
 178  
                 }
 179  125
                 log.debug("about to load rules to read master record");
 180  125
                 Digester masterRecordDigester = DigesterLoader.createDigester(rules);
 181  125
                 return masterRecordDigester;
 182  
         }
 183  
         
 184  
 }