diff commons/core/checker/ConfigChecker.py @ 6:769e306b7933

Change the repository level.
author yufei-luo
date Fri, 18 Jan 2013 04:54:14 -0500
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/commons/core/checker/ConfigChecker.py	Fri Jan 18 04:54:14 2013 -0500
@@ -0,0 +1,226 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import re
+import sys
+from commons.core.utils.RepetConfigParser import RepetConfigParser
+from commons.core.checker.ConfigValue import ConfigValue
+from commons.core.checker.IChecker import IChecker
+from commons.core.checker.RepetException import RepetException
+from commons.core.utils.FileUtils import FileUtils
+
+
+class Rule(object):
+    
+    def __init__(self, mandatory= False, isPattern=False, type="", set=(), help =""):
+        self.mandatory = mandatory
+        self.isPattern = isPattern
+        self.type = type
+        self.set = set
+        self.help = help
+        
+class ConfigRules(object):
+    
+    def __init__(self, configName = "", configDescription = ""):
+        self.configName = configName
+        self.configDescription = configDescription
+        self.dRules4Sections={}
+        
+    def _addRule(self, section, option="DEFAULT", mandatory=False, isPattern=False, type="", set=(), help =""):
+        if not self.dRules4Sections.has_key(section):
+            self.dRules4Sections[section] = {}
+        self.dRules4Sections[section][option]=Rule(mandatory, isPattern, type.lower(), set) 
+        
+    def addRuleSection(self, section, mandatory=False, isPattern=False, help = ""):
+        self._addRule(section = section, option = "DEFAULT", mandatory = mandatory, isPattern =  isPattern, help = "")
+   
+    def addRuleOption(self, section, option, mandatory=False, isPattern=False, type="", set=(), help = ""):
+        self._addRule(section = section, option = option, mandatory = mandatory, isPattern =  isPattern, type = type, set=set , help = "")
+            
+    def isSectionMandatory(self, section):
+        if self.dRules4Sections.has_key(section):
+            if self.dRules4Sections[section].has_key("DEFAULT"):
+                return self.dRules4Sections[section]["DEFAULT"].mandatory
+        return False
+        
+    def isOptionMandatory(self, section, option):
+        if self.dRules4Sections.has_key(section):
+            if self.dRules4Sections[section].has_key(option):
+                return self.dRules4Sections[section][option].mandatory
+        return False
+    
+    def getRule(self, section, option):
+        if self.dRules4Sections.has_key(section):
+            if self.dRules4Sections[section].has_key(option):
+                return self.dRules4Sections[section][option]
+        return None
+    
+class ConfigChecker(IChecker):
+    
+    def __init__ (self, cfgFileName, iCfgRules):
+        self._configFileName = cfgFileName
+        self._iConfigRules = iCfgRules
+        self._iRawConfig = ConfigValue()
+        self._iExtendedConfigRules = ConfigRules()
+        
+    def readConfigFile(self):
+        iConfig = RepetConfigParser()
+        try:
+            iConfig.readfp(open(self._configFileName))
+            return iConfig
+# TODO USE OF CONFIG ERROR
+#            if DuplicateSectionError:
+#                raise Exception ("Duplicate section exist in config file %s" %(self._configFileName ))
+        except :
+            raise RepetException ("Unexpected error: %s" %  sys.exc_info()[0])
+        
+    def setRawConfig(self, iConfig ):
+        for sectionName in iConfig.sections(): 
+            for optionName in iConfig.options(sectionName):
+                optionValue = iConfig.get(sectionName, optionName)
+                self._iRawConfig.set(sectionName, optionName, optionValue)
+                
+    def getOptionValueAccordingRule(self, iConfig, sectionName, optionName):
+        optionRule = self._iExtendedConfigRules.getRule(sectionName, optionName)
+        if optionRule == None : 
+            return iConfig.get(sectionName, optionName)
+        
+        if optionRule.type == "int":
+            optionValue = iConfig.getint(sectionName, optionName)
+        elif optionRule.type == "float":
+            optionValue = iConfig.getfloat(sectionName, optionName)
+        elif optionRule.type == "bool" or optionRule.type == "boolean":
+            optionValue = iConfig.getboolean(sectionName, optionName)
+        else:
+            optionValue = iConfig.get(sectionName, optionName)
+        if optionRule.set!=() and not(optionValue in optionRule.set):  
+            #TODO : test and fix    
+            raise RepetException ("value must be in %s " % set.__repr__())
+        
+        return optionValue
+    
+    def setConfig(self, iConfig ):
+        config = ConfigValue()
+        valueErr = ""
+        for sectionName in iConfig.sections():
+            for optionName in iConfig.options(sectionName):
+                try:    
+                    optionValue = self.getOptionValueAccordingRule(iConfig, sectionName, optionName )
+                    config.set(sectionName, optionName, optionValue)
+                except RepetException, re :
+                    #TODO : test and fix    
+                    valueErr += "\n - [%s]: %s %s" % re.getMessage()
+        if valueErr == "":
+            self._iRawConfig = config
+        else:
+            raise RepetException ("Following errors occurs:%s\n" %valueErr)
+        
+    def checkIfExistsConfigFile (self):   
+        if not (FileUtils.isRessourceExists(self._configFileName)):
+            raise RepetException("CONFIG FILE not found - '%s'" % self._configFileName)
+    
+    def checkMandatorySections (self):
+        missingSection = ""
+        for sectionName in self._iExtendedConfigRules.dRules4Sections.keys():
+            if self._iExtendedConfigRules.isSectionMandatory(sectionName) and not self._iRawConfig.has_section(sectionName):
+                    missingSection += "\n - %s" %(sectionName)
+        if missingSection != "":
+            raise RepetException ("Error in configuration file %s, following sections are missing:%s\n" % (self._configFileName, missingSection))
+    
+    def checkMandatoryOptions (self):
+        missingOption = ""
+        for sectionName in self._iExtendedConfigRules.dRules4Sections.keys():
+            if self._iExtendedConfigRules.isSectionMandatory(sectionName) or self._iRawConfig.has_section(sectionName) :
+                dRules4OptionsOfThisSection = self._iExtendedConfigRules.dRules4Sections[sectionName]
+                for optionName in dRules4OptionsOfThisSection.keys():
+                    if optionName != "DEFAULT" and self._iExtendedConfigRules.isOptionMandatory(sectionName, optionName) and not self._iRawConfig.has_option(sectionName, optionName):
+                        missingOption += "\n - [%s]: %s" % (sectionName, optionName)
+        if missingOption != "":
+            raise RepetException ("Error in configuration file %s, following options are missing: %s\n" % (self._configFileName, missingOption))
+    
+    def getSectionNamesAccordingPatternRules (self, sectionWordOrPattern, isPattern):          
+        lSectionsFoundAccordingPatternRules=[]
+        if isPattern == False:
+            if self._iRawConfig.has_section(sectionWordOrPattern):
+                lSectionsFoundAccordingPatternRules.append(sectionWordOrPattern)
+        else:
+            for sectionName in self._iRawConfig.sections():
+                if re.search(sectionWordOrPattern, sectionName, re.IGNORECASE):
+                    lSectionsFoundAccordingPatternRules.append(sectionName)
+        return lSectionsFoundAccordingPatternRules
+    
+    def getOptionsNamesAccordingPatternRules(self, sectionName, optionWordOrPattern, isPattern):
+        lOptionsFoundAccordingPatternRules=[]
+        if isPattern == False:
+            if self._iRawConfig.has_option(sectionName, optionWordOrPattern):
+                lOptionsFoundAccordingPatternRules.append(optionWordOrPattern)
+        else :
+            for optionName in self._iRawConfig.options(sectionName):
+                if re.search(optionWordOrPattern, optionName, re.IGNORECASE)!= None:
+                    lOptionsFoundAccordingPatternRules.append(optionName)
+        return lOptionsFoundAccordingPatternRules
+    
+    def extendConfigRulesWithPatternRules(self):
+        for sectionName in self._iConfigRules.dRules4Sections.keys():
+            dRules4OptionsOfThisSection = self._iConfigRules.dRules4Sections[sectionName] 
+            lRawSections=[]
+            if dRules4OptionsOfThisSection.has_key("DEFAULT"):
+                mandatorySection = dRules4OptionsOfThisSection["DEFAULT"].mandatory
+                isPatternSection = dRules4OptionsOfThisSection["DEFAULT"].isPattern
+                lRawSections=self.getSectionNamesAccordingPatternRules(sectionName, isPatternSection)
+                for rawSectionName in lRawSections:
+                    self._iExtendedConfigRules.addRuleSection(rawSectionName, "DEFAULT", mandatorySection )
+                if mandatorySection and (len(lRawSections)==0):
+                    self._iExtendedConfigRules.addRuleSection(sectionName, "DEFAULT", mandatorySection )
+            else:
+                lRawSections.append(sectionName) 
+            for optionName in dRules4OptionsOfThisSection.keys():
+                setOption = dRules4OptionsOfThisSection[optionName].set
+                isPatternOption = dRules4OptionsOfThisSection[optionName].isPattern
+                mandatoryOption = dRules4OptionsOfThisSection[optionName].mandatory
+                typeOption = dRules4OptionsOfThisSection[optionName].type
+                if optionName != "DEFAULT":
+                    for rawSectionName in lRawSections:
+                        lRawOptions=self.getOptionsNamesAccordingPatternRules(rawSectionName, optionName, isPatternOption)
+                        for rawOptionName in lRawOptions:
+                            self._iExtendedConfigRules.addRuleOption(rawSectionName, rawOptionName, mandatoryOption, False, typeOption, setOption)
+                        if mandatoryOption and (len(lRawOptions)==0):
+                            self._iExtendedConfigRules.addRuleOption(rawSectionName, optionName, mandatoryOption, False, typeOption, setOption)
+                                                          
+    def getConfig(self):
+        self.checkIfExistsConfigFile()
+        iConfig = self.readConfigFile()
+        self.setRawConfig(iConfig)
+        self.extendConfigRulesWithPatternRules()
+        self.checkMandatorySections()
+        self.checkMandatoryOptions()
+        self.setConfig(iConfig)
+        return self._iRawConfig
\ No newline at end of file