1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
from xml.etree.ElementTree import *
import sys
import xml
import pdb
import util.Strings as Strings
from logger import main_log, exception_log
classArgsMem = {}
CONFIG_PATH = 'config/'
def loadParamRequirementDict(className):
if not className in classArgsMem: #WOO CACHING
classArgsMem[className] = fileToDict(CONFIG_PATH + className)
return classArgsMem[className]
#Loads a config file. If its an xml file, inheritances are automatically resolved.
def loadConfigFile(fileName): #TODO: error handling etc.
try:
if '.params' in fileName:
return fileToDict(fileName)
if '.xml' in fileName:
config = ElementTree() #use .fromstring, and resolve xincludes
config.parse(fileName)
config = ElementTree(resolveConfigInheritance(config.getroot()))
return config
except Exception as inst:
main_log.error('Error loading config file ' + fileName)#, inst) TODO: log exception too
return None
#Takes an Element or an ElementTree. If it is a tree, it returns its root. Otherwise, just returns
#it
def getElement(el):
if xml.etree.ElementTree.iselement(el):
return el
elif el.__class__ == ElementTree:
return el.getroot()
def compositeXMLTrees(parentTree, overridingTree): #TODO: break up into sub-methods, change it to
#use .find()
#type checking -- convert ElementTrees to their root elements
if parentTree == None:
return overridingTree
if overridingTree == None:
return parentTree
parentTree = getElement(parentTree)
overridingTree = getElement(overridingTree)
parentItems = parentTree.getchildren()
overrideItems = overridingTree.getchildren()
#first, lets figure out what tags we have in the override tree:
tagCollection = [el.tag for el in overrideItems] #we can speed this up with a dict if necessary
for item in parentItems:
if not item.tag in tagCollection: #no override
overridingTree.insert(-1, item) #insert the new item at the end
else:
#do we merge or replace?
intersectingElements = findElementsByTag(item.tag, overrideItems)
if len(intersectingElements) > 1:
main_log.warn('ABUSE! Override of multiple items isn\'t well defined. Don\'t do\
it!')
interEl = intersectingElements[0]
mode = 'Replace'
if Strings.OVERRIDE_BEHAVIOR in interEl.attrib:
mode = interEl.attrib[Strings.OVERRIDE_BEHAVIOR]
if mode != 'Replace' and mode != 'Merge':
main_log.warn('Bad Override Mode. Choosing to replace.')
mode = 'Replace'
if mode == 'Replace':
pass #we don't need to do anything
if mode == 'Merge':
interEl = compositeXMLTrees(item, interEl)
for item in overrideItems: #resolve appendages
if item.tag == 'APPEND':
children = item.getchildren()
for child in children:
overrideItems.insert(-1, child)
overrideItems.remove(item)
return overridingTree
def findElementsByTag(tag, eList):
return [el for el in eList if el.tag == tag]
def fileToDict(fileName):
fileText = ''
try:
with open(fileName) as f:
for line in f:
fileText += line.rstrip('\n').lstrip('\t') + ' '
except IOError:
exception_log.exception('Failure reading ' + fileName)
return {}
if fileText == '':
return {}
try:
resultDict = eval(fileText)
main_log.info(fileName + ' read and parsed')
return resultDict
except:
exception_log.info(fileName + ' is not a well formed python dict. Parsing failed')
return eval(fileText)
#parses arguments into python objects if possible, otherwise leaves as strings
def generateArgDict(parentNode, recurse=False):
args = {}
for arg in parentNode.getchildren():
key = arg.tag
if arg.getchildren() != []:
value = generateArgDict(arg, True)
else:
#convert into python if possible, otherwise don't
try:
value = eval(arg.text)
except (NameError,SyntaxError):
value = str(arg.text)
if key in args: #build of lists of like-elements
if type(args[key]) != type([]):
args[key] = [args[key]]
args[key].append(value)
else:
args[key]=value
#if we should be a list but we aren't:
if len(args.keys()) == 1 and recurse:
return args[args.keys()[0]]
return args
def resolveConfigInheritance(el):
parentClass = el.find('InheritsFrom')
if parentClass != None:
parentTree = loadConfigFile(parentClass.text)
if parentTree == None:
main_log.warn('Inheritance Failed. ' + parentClass.text + 'does not exist')
main_log.error('Inheritance Failed. ' + parentClass.text + 'does not exist')
return el
el = compositeXMLTrees(el, parentTree)
el.remove(parentClass) #get rid of the inheritance flag
return el
|