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

Source Code for Module configParser

  1   
  2  import os, sys, dynamic, time, glob 
  3  from utils import getFirstData, elementType 
  4  from bootstrap import BSParser, BootstrapDocument 
  5  from c3errors import FileDoesNotExistException, ConfigFileException, PermissionException, ObjectDoesNotExistException 
  6  from types import MethodType 
  7  from permissionHandler import PermissionHandler 
  8   
9 -class C3Object(object):
10 id = "" 11 name = "" 12 objectType = "" 13 parent = None 14 paths = {} 15 subConfigs = {} 16 objects = {} 17 configStore = None 18 settings = {} 19 defaults = {} 20 functionLogger = None 21 permissionHandlers = {} 22 23 unresolvedObjects = {} 24 25 # temp storage 26 _includeConfigStores = [] 27 _objectRefs = [] 28 29
30 - def _getDomFromFile(self, session, fileName):
31 """Read in an XML file from disk to get the configuration for this object.""" 32 # We need to be able to read in configurations from disk 33 34 if not os.path.exists(fileName): 35 raise(FileDoesNotExistException(fileName)) 36 37 f = file(fileName) 38 doc = BootstrapDocument(f) 39 40 # Look on self for instantiated parser, otherwise use bootstrap 41 p = self.get_path(session, 'parser') 42 if (p <> None): 43 # Not sure if this ever occurs... 44 record = p.process_document(session, doc) 45 else: 46 record = BSParser.process_document(session,doc) 47 dom = record.get_dom() 48 return dom
49 50
51 - def _handleConfigNode(self, session, node):
52 pass
53 54 # Return parsed value (eg Int, Bool, String etc) 55 # Or raise an error
56 - def _verifyOption(self, type, value):
57 return value
58 - def _verifySetting(self, type, value):
59 return self._verifyOption(type, value)
60 - def _verifyDefault(self, type, value):
61 return self._verifyOption(type, value)
62 63
64 - def _parseIncludes(self, session, path):
65 dom = self._getDomFromFile(session, path) 66 for child2 in dom.childNodes[0].childNodes: 67 if child2.nodeType == elementType: 68 if child2.localName == "subConfigs": 69 self._recurseSubConfigs(session, child2) 70 elif (child2.localName == "objects"): 71 # record object ref to instantiate 72 for obj in child2.childNodes: 73 if (obj.nodeType == elementType and obj.localName == "path"): 74 type = obj.getAttributeNS(None,'type') 75 id = obj.getAttributeNS(None,'ref') 76 self._objectRefs.append((id, type))
77
78 - def _recurseSubConfigs(self, session, child):
79 for mod in child.childNodes: 80 if mod.nodeType == elementType and mod.localName == "subConfig": 81 id = mod.getAttributeNS(None,'id') 82 self.subConfigs[id] = mod 83 84 # Cache indexes and maps 85 type = mod.getAttributeNS(None,'type') 86 if type == 'index': 87 self.indexConfigs[id] = mod 88 elif type == 'protocolMap': 89 self.protocolMapConfigs[id] = mod 90 elif type == 'database': 91 self.databaseConfigs[id] = mod 92 elif type == '': 93 raise ConfigFileException("Object must have a type attribute: %s" % id) 94 95 elif mod.nodeType == elementType and mod.localName == "path": 96 if (mod.hasAttribute('type') and mod.getAttributeNS(None,'type') == 'includeConfigs'): 97 # Import into our space 98 if (mod.hasAttribute('ref')): 99 # <path type="includeConfigs" ref="configStore"/> 100 self._includeConfigStores.append(mod.getAttributeNS(None,'ref')) 101 else: 102 # <path type="includeConfigs">path/to/some/file.xml</path> 103 path = getFirstData(mod) 104 if not os.path.isabs(path): 105 path = os.path.join(self.get_path(None, 'defaultPath'), path) 106 if os.path.isdir(path): 107 # include all configs in it at our space 108 files = glob.glob("%s/*.xml" % path) 109 for f in files: 110 self._parseIncludes(session, f) 111 else: 112 self._parseIncludes(session, path) 113 else: 114 path = getFirstData(mod) 115 if not os.path.isabs(path): 116 path = os.path.join(self.get_path(session, 'defaultPath'), path) 117 dom = self._getDomFromFile(session, path) 118 id = mod.getAttributeNS(None,'id') 119 self.subConfigs[id] = dom.childNodes[0] 120 ot = mod.getAttributeNS(None,'type') 121 if ot == 'database': 122 self.databaseConfigs[id] = dom.childNodes[0]
123
124 - def __init__(self, session, topNode, parentObject=None):
125 """The constructor for all Cheshire3 objects take the same arguments: 126 session: A Session object 127 topNode: The <config> or <subConfig> domNode for the configuration 128 parent: The object that provides the scope for this object. 129 """ 130 131 132 self.docstring = "" 133 self.parent = parentObject 134 self.subConfigs = {} 135 self.paths = {} 136 self.objects = {} 137 self.settings = {} 138 self.defaults = {} 139 self.permissionHandlers = {} 140 self.unresolvedObjects = {} 141 self.functionLogger = None 142 self._objectRefs = [] 143 self._includeConfigStores = [] 144 pathObjects = {} 145 146 try: 147 if (topNode.hasAttribute('id')): 148 self.id = topNode.getAttributeNS(None,'id') 149 except: 150 if (topNode.hasAttributeNS(None, 'id')): 151 self.id = topNode.getAttributeNS(None, 'id') 152 153 for child in topNode.childNodes: 154 if child.nodeType == elementType: 155 if child.localName == "name": 156 self.name = getFirstData(child) 157 elif (child.localName == "objectType"): 158 self.objectType = getFirstData(child) 159 elif (child.localName == "paths"): 160 # Configure self with paths 161 for child2 in child.childNodes: 162 if child2.nodeType == elementType: 163 type = child2.getAttributeNS(None, 'type') 164 if child2.localName == "path": 165 value = getFirstData(child2) 166 self.paths[type] = value 167 elif child2.localName == "object": 168 value = child2.getAttributeNS(None,'ref') 169 pathObjects[type] = value 170 elif (child.localName == "imports"): 171 # Do this now so we can reference 172 for mod in child.childNodes: 173 if mod.nodeType == elementType and mod.localName == "module": 174 name, objects, withname = ('', [], None) 175 for n in mod.childNodes: 176 if (n.nodeType == elementType): 177 if (n.localName == 'name'): 178 name = getFirstData(n) 179 elif (n.localName == 'object'): 180 objects.append(getFirstData(n)) 181 elif (n.localName == 'withName'): 182 withname = getFirstData(n) 183 if (name): 184 dynamic.globalImport(name, objects, withname) 185 else: 186 raise(ConfigFileException('No name given for module to import in configFile for %s' % (self.id))) 187 188 elif (child.localName == "subConfigs"): 189 # Pointers to dom nodes for config ids 190 self._recurseSubConfigs(session, child) 191 192 elif (child.localName == "objects"): 193 for obj in child.childNodes: 194 if (obj.nodeType == elementType and obj.localName == "path"): 195 type = obj.getAttributeNS(None,'type') 196 id = obj.getAttributeNS(None,'ref') 197 self._objectRefs.append((id, type)) 198 elif (child.localName == "options"): 199 # See configInfo in ZeeRex 200 for child2 in child.childNodes: 201 if (child2.nodeType == elementType): 202 type = child2.getAttributeNS(None,'type') 203 if (child2.localName == "setting"): 204 dc = getFirstData(child2) 205 if (dc): 206 value = self._verifySetting(type, dc) 207 self.settings[type] = value 208 elif (child2.localName == "default"): 209 dc = getFirstData(child2) 210 if (dc): 211 value = self._verifyDefault(type, dc) 212 self.defaults[type] = value 213 elif (child.localName == "actions"): 214 # permission rqmts 215 for child2 in child.childNodes: 216 if child2.nodeType == elementType: 217 p = PermissionHandler(child2, self) 218 self.permissionHandlers[p.actionIdentifier] = p 219 elif (child.localName == "docs"): 220 # Add per configuration documentation to docs stack. 221 self.docstring = getFirstData(child) 222 else: 223 self._handleConfigNode(session, child) 224 225 if (self.paths.has_key("pythonPath")): 226 sys.path.append(self.paths['pythonPath'][1]) 227 228 for p in self.permissionHandlers.keys(): 229 if p[0:5] == 'c3fn:': 230 self.auth_function(p[5:]) 231 232 # Built, maybe set function logging 233 log = self.get_setting(session, 'log') 234 if (log): 235 logList = log.strip().split() 236 for l in logList: 237 self.log_function(l) 238 del self.settings['log'] 239 240 # Dynamically Instantiate objects. This is mindbending :} 241 # Mindbending2: JIT building! 242 if self.parent: 243 self.parent.objects[self.id] = self 244 for o in (self._objectRefs): 245 # Instantiate 246 obj = self.get_object(session, o[0]) 247 248 # Add default Object types to paths 249 for t in pathObjects.keys(): 250 self.unresolvedObjects[t] = pathObjects[t] 251 252 # Now check for configStore objects 253 for csid in self._includeConfigStores: 254 confStore = self.get_object(session, csid) 255 if confStore != None: 256 for rec in confStore: 257 # do something with config 258 node = rec.get_dom() 259 node= node.childNodes[0] 260 nid = node.getAttributeNS(None, 'id') 261 self.subConfigs[nid] = node 262 ntype = node.getAttributeNS(None, 'type') 263 if ntype == 'index': 264 self.indexConfigs[nid] = node 265 elif ntype == 'protocolMap': 266 self.protocolMapConfigs[nid] = node 267 elif ntype == 'database': 268 self.databaseConfigs[nid] = node 269 elif ntype == '': 270 raise ConfigFileException("Object must have a type attribute: %s -- in configStore %s" % (nid, csid))
271 272
273 - def get_setting(self, session, id, default=None):
274 """Return the value for a setting on this object.""" 275 return self.settings.get(id, default)
276
277 - def get_default(self, session, id, default=None):
278 """Return the default value for an option on this object""" 279 return self.defaults.get(id, default)
280
281 - def get_object(self, session, id):
282 """Return an object with the given id within this object's scope, or search upwards for it.""" 283 if (self.objects.has_key(id)): 284 return self.objects[id] 285 else: 286 config = self.get_config(session, id) 287 if config: 288 try: 289 obj = dynamic.makeObjectFromDom(session, config, self) 290 except ConfigFileException: 291 # Push back up 292 raise 293 return obj 294 elif (self.parent <> None): 295 return self.parent.get_object(session, id) 296 else: 297 raise ObjectDoesNotExistException(id)
298
299 - def get_config(self, session, id):
300 """Return a configuration for the given object.""" 301 if (self.subConfigs.has_key(id)): 302 return self.subConfigs[id] 303 #elif (self.parent <> None): 304 # return self.parent.get_config(session, id) 305 else: 306 return None
307
308 - def get_path(self, session, id, default=None):
309 """Return the named path""" 310 if (self.paths.has_key(id)): 311 path = self.paths[id] 312 # Special handling for defaultPath :/ 313 if (id == "defaultPath" and not os.path.isabs(path)): 314 p1 = self.parent.get_path(session, id, default) 315 path = os.path.join(p1, path) 316 return path 317 elif (self.unresolvedObjects.has_key(id)): 318 o = self.get_object(session, self.unresolvedObjects[id]) 319 self.paths[id] = o 320 del self.unresolvedObjects[id] 321 return o 322 elif (self.parent <> None): 323 return self.parent.get_path(session, id, default) 324 else: 325 return default
326
327 - def log_function(self, name):
328 """ Set a named function to log invocations.""" 329 if (name == "__all__"): 330 names = dir(self) 331 else: 332 names = [name] 333 for name in names: 334 if (hasattr(self, name) and callable(getattr(self,name)) and name[0] <> '_'): 335 func = getattr(self, name) 336 setattr(self, "__postlog_%s" % (name), getattr(self, name)) 337 code = """def mylogfn(self, *args, **kw):\n if (hasattr(self,'__postlog_get_path')):\n fn = self.__postlog_get_path\n else:\n fn = self.get_path\n fl = fn(None, 'functionLogger');\n if (fl):\n fl.log(self, '%s', *args, **kw);\n return self.__postlog_%s(*args, **kw);""" % (name, name) 338 exec code 339 setattr(self, name, MethodType(locals()['mylogfn'], self, self.__class__))
340
341 - def unlog_function(self, name):
342 """Remove the logging from a named function.""" 343 if (name == "__all__"): 344 names = dir(self) 345 else: 346 names = [name] 347 for name in names: 348 if (hasattr(self, name) and callable(getattr(self,name)) and name[0] <> '_' and hasattr(self, '__postlog_%s' % name)): 349 setattr(self, name, getattr(self, '__postlog_%s' % name)) 350 delattr(self, '__postlog_%s' % name)
351
352 - def auth_function(self, name):
353 """Add an authorisation layer on top of a named function.""" 354 if (hasattr(self, name) and callable(getattr(self,name)) and name[0] <> '_'): 355 func = getattr(self, name) 356 setattr(self, "__postauth_%s" % (name), func) 357 code = """ 358 def myauthfn(self, session, *args, **kw): 359 p = self.permissionHandlers['c3fn:%s'] 360 if (p): 361 if not session or not session.user: 362 raise PermissionException('Authenticated user required to call %s') 363 if not p.hasPermission(session, session,user): 364 raise PermissionException('Permission required to call %s') 365 return self.__postauth_%s(*args, **kw); 366 """ % (name, name, name, name) 367 exec code 368 setattr(self, name, MethodType(locals()['myauthfn'], self, self.__class__))
369 370
371 - def unauth_function(self, name):
372 """Remove the authorisation requirement from the named function.""" 373 if (name == "__all__"): 374 names = dir(self) 375 else: 376 names = [name] 377 for name in names: 378 if (hasattr(self, name) and callable(getattr(self,name)) and name[0] <> '_' and hasattr(self, '__postauth_%s' % name)): 379 setattr(self, name, getattr(self, '__postauth_%s' % name)) 380 delattr(self, '__postauth_%s' % name)
381