Module configuration_model
[hide private]
[frames] | no frames]

Source Code for Module configuration_model

  1  #============================================================================  
  2  #Name        : configuration_model.py  
  3  #Part of     : Helium  
  4   
  5  #Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
  6  #All rights reserved. 
  7  #This component and the accompanying materials are made available 
  8  #under the terms of the License "Eclipse Public License v1.0" 
  9  #which accompanies this distribution, and is available 
 10  #at the URL "http://www.eclipse.org/legal/epl-v10.html". 
 11  # 
 12  #Initial Contributors: 
 13  #Nokia Corporation - initial contribution. 
 14  # 
 15  #Contributors: 
 16  # 
 17  #Description: 
 18  #=============================================================================== 
 19   
 20  import amara 
 21  from amara import bindery 
 22  import logging 
 23  import types 
 24  import copy 
 25   
 26  _logger = logging.getLogger('configurationmodel') 
 27  #logging.basicConfig(level=logging.DEBUG) 
 28  _handler = logging.StreamHandler() 
 29  _handler.setFormatter(logging.Formatter('%(levelname)s: %(message)s')) 
 30  _logger.addHandler(_handler) 
 31   
 32   
33 -class PropertyDef(object):
34 """ The model definition of a property. """ 35
36 - def __init__(self, property_node):
37 """ Initialization. """ 38 if not hasattr(property_node, 'name'): 39 raise Exception("Name is not defined for '" + str(property_node) + "'") 40 if not hasattr(property_node, 'type'): 41 raise Exception("Type is not defined for '" + str(property_node.name) + "'") 42 if not hasattr(property_node, 'description'): 43 raise Exception("Description is not defined for '" + str(property_node.name) + "'") 44 45 self.name = str(property_node.name) 46 self.editStatus = str(property_node.editStatus) 47 self.type = str(property_node.type) 48 self.description = str(property_node.description).strip() 49 50 if len(self.description) == 0: 51 _logger.log(logging.ERROR, "Description has no content for '" + str(property_node.name) + "'") 52 53 if hasattr(property_node, 'deprecated'): 54 self.deprecated = str(property_node.deprecated)
55
56 - def __repr__(self):
57 return self.name
58
59 - def __str__(self):
60 return self.name
61 62
63 -class GroupDef(object):
64 """ The model definition of a group of properties. """
65 - def __init__(self, group_node):
66 """ Initialization. """ 67 self.name = str(group_node.name) 68 self.description = str(group_node.description) 69 self.properties = {} 70 self.propref = [] 71 for property_ in group_node.propertyRef: 72 self.properties[str(property_)] = property_.usage
73
74 - def check_config(self, config, items):
75 """ Checks that the set of properties in a group are properly defined. """ 76 defined_props = [p for p in self.properties.keys() if config.has_key(p)] 77 if len(defined_props) > 0: 78 required_props = [p for p in self.properties.keys() if self.properties[p] == 'required'] 79 required_not_defined_props = set(required_props).difference(set(defined_props)) 80 for undefined_property in required_not_defined_props: 81 items.append(UndefinedRequiredInGroupItem((self.name, undefined_property)))
82 83
84 -class DataModel(object):
85 """ A model of the configuration properties. """
86 - def __init__(self, modelpath):
87 """ Initialization. """ 88 doc = amara.parse(open(modelpath, 'r')) 89 90 self.properties = {} 91 self.required_props = [] 92 for property_ in doc.heliumDataModel.property: 93 self.properties[str(property_.name)] = PropertyDef(property_) 94 95 self.nongroupedproperties = copy.copy(self.properties) 96 self.groups = {} 97 for group in doc.heliumDataModel.group: 98 groupobj = GroupDef(group) 99 self.groups[str(group.name)] = groupobj 100 101 for prop in groupobj.properties: 102 groupobj.propref.append(self.properties[prop]) 103 if prop in self.nongroupedproperties: 104 del self.nongroupedproperties[prop] 105 106 groupobj.propref.sort() 107 108 required_props_in_group = [p for p in group.propertyRef if p.usage == 'required'] 109 110 for required_prop in required_props_in_group: 111 self.required_props.append(required_prop) 112 if not self.properties.has_key(str(required_prop)): 113 raise Exception("Required property " + str(required_prop) + " is not defined!")
114
115 - def validate_config(self, config):
116 """ Validate the Ant configuration against the model. """ 117 items = [] 118 self._check_deprecated_properties(config, items) 119 self._check_undefined_properties(config, items) 120 self._check_undefined_properties_in_groups(config, items) 121 self._check_type_validation(config, items) 122 self._check_defined_properties_not_in_groups(config, items) 123 return items
124
125 - def validate_config_at_startup(self, config):
126 """ Validate the Ant configuration against the model at build startup. """ 127 items = [] 128 129 for p in self.required_props: 130 if not config.has_key(str(p)): 131 print "Required property " + str(p) + " is not defined!" 132 133 return items
134
135 - def _check_deprecated_properties(self, config, items):
136 """ Check that deprecated properties not being used. """ 137 deprecated_props = [p for p in self.properties.values() if hasattr(p, 'deprecated')] 138 for deprecated_prop in deprecated_props: 139 _logger.debug('Checking deprecated property: ' + str(deprecated_prop)) 140 if config.has_key(str(deprecated_prop)): 141 items.append(UsingDeprecatedItem(deprecated_prop))
142
143 - def _check_undefined_properties(self, config, items):
144 """ Check for any defined properties that are not in the model. """ 145 undefined_properties = [p for p in config.keys() if p not in self.properties] 146 undefined_properties.sort() 147 for undefined_property in undefined_properties: 148 items.append(MissingFromDataModelItem(undefined_property))
149
150 - def _check_undefined_properties_in_groups(self, config, items):
151 for group in self.groups.values(): 152 _logger.debug('Checking group: %s' % group.name) 153 group.check_config(config, items)
154
155 - def _check_defined_properties_not_in_groups(self, config, items):
156 gp = [] 157 for group in self.groups.values(): 158 gp = gp + group.properties.keys() 159 for p in self.properties.values(): 160 if not str(p) in gp: 161 raise Exception(str(p) + ' not in a group')
162
163 - def _check_type_validation(self, config, items):
164 prop_string = [p for p in self.properties.values() if p.type == 'string'] 165 prop_integer = [p for p in self.properties.values() if p.type == 'integer'] 166 prop_boolean = [p for p in self.properties.values() if p.type == 'boolean'] 167 prop_flag = [p for p in self.properties.values() if p.type == 'flag'] 168 169 for prop in prop_integer: 170 if config.has_key(str(prop)): 171 if not config[str(prop)].isdigit(): 172 items.append(WrongTypeItem(("integer", prop))) 173 174 for prop in prop_boolean: 175 if config.has_key(str(prop)) : 176 if not (config[str(prop)] == 'false' or 'true'): 177 items.append(WrongTypeItem(("boolean", prop))) 178 179 for prop in prop_string: 180 if config.has_key(str(prop)): 181 if len(config[str(prop)]) == 0: 182 items.append(WrongTypeItem(("string", prop)))
183 184
185 -class Item(object):
186 level = logging.INFO 187 message = '' 188
189 - def __init__(self, values):
190 """ Initialization. """ 191 self.values = values
192
193 - def log(self, logger):
194 logger.log(self.level, str(self))
195
196 - def __str__(self):
197 return self.message % self.values
198 199
200 -class MissingFromDataModelItem(Item):
201 level = logging.INFO 202 message = 'Property not in data model: %s'
203 204
205 -class UsingDeprecatedItem(Item):
206 level = logging.WARNING 207 message = 'Deprecated property used: %s'
208 209
210 -class UndefinedRequiredInGroupItem(Item):
211 level = logging.WARNING 212 message = 'Required property in %s group is not defined: %s'
213 214
215 -class WrongTypeItem(Item):
216 level = logging.WARNING 217 message = 'Invalid %s value: %s'
218