1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 import os, os.path, sys, string, logging, time, xml.dom.minidom
21
22 from pysys.constants import *
23
24 log = logging.getLogger('pysys.xml.project')
25
26 DTD='''
27 <!DOCTYPE pysysproject [
28 <!ELEMENT pysysproject (property*, path*, runner?, writers?, formatters?) >
29 <!ELEMENT property (#PCDATA)>
30 <!ELEMENT path (#PCDATA)>
31 <!ELEMENT runner (#PCDATA)>
32 <!ELEMENT formatters (formatter+) >
33 <!ELEMENT formatter (#PCDATA) >
34 <!ELEMENT writers (writer+) >
35 <!ELEMENT writer (property*) >
36 <!ATTLIST property root CDATA #IMPLIED>
37 <!ATTLIST property environment CDATA #IMPLIED>
38 <!ATTLIST property osfamily CDATA #IMPLIED>
39 <!ATTLIST property file CDATA #IMPLIED>
40 <!ATTLIST property name CDATA #IMPLIED>
41 <!ATTLIST property value CDATA #IMPLIED>
42 <!ATTLIST property default CDATA #IMPLIED>
43 <!ATTLIST path value CDATA #REQUIRED>
44 <!ATTLIST path relative CDATA #IMPLIED>
45 <!ATTLIST runner classname CDATA #REQUIRED>
46 <!ATTLIST runner module CDATA #REQUIRED>
47 <!ATTLIST formatter name CDATA #REQUIRED>
48 <!ATTLIST formatter messagefmt CDATA #REQUIRED>
49 <!ATTLIST formatter datefmt CDATA #REQUIRED>
50 <!ATTLIST writer classname CDATA #REQUIRED>
51 <!ATTLIST writer module CDATA #REQUIRED>
52 <!ATTLIST writer file CDATA #IMPLIED>
53 ]>
54 '''
55
56 PROPERTY_EXPAND_ENV = "(?P<replace>\${%s.(?P<key>.*?)})"
57 PROPERTY_EXPAND = "(?P<replace>\${(?P<key>.*?)})"
58 PROPERTY_FILE = "(?P<name>^.*)=(?P<value>.*)$"
59
60
63 self.dirname = dirname
64 self.xmlfile = os.path.join(dirname, file)
65 self.rootdir = 'root'
66 self.environment = 'env'
67 self.osfamily = 'osfamily'
68 self.properties = {self.rootdir:self.dirname, self.osfamily:OSFAMILY}
69
70 if not os.path.exists(self.xmlfile):
71 raise Exception, "Unable to find supplied project file \"%s\"" % self.xmlfile
72
73 try:
74 self.doc = xml.dom.minidom.parse(self.xmlfile)
75 except:
76 raise Exception, sys.exc_info()[1]
77 else:
78 if self.doc.getElementsByTagName('pysysproject') == []:
79 raise Exception, "No <pysysproject> element supplied in project file"
80 else:
81 self.root = self.doc.getElementsByTagName('pysysproject')[0]
82
83
85 if self.doc: self.doc.unlink()
86
87
89 propertyNodeList = self.root.getElementsByTagName('property')
90
91 for propertyNode in propertyNodeList:
92 if propertyNode.hasAttribute("environment"):
93 self.environment = propertyNode.getAttribute("environment")
94
95 elif propertyNode.hasAttribute("root"):
96 self.properties.pop(self.rootdir, "")
97 self.rootdir = propertyNode.getAttribute("root")
98 self.properties[self.rootdir] = self.dirname
99
100 elif propertyNode.hasAttribute("osfamily"):
101 self.properties.pop(self.osfamily, "")
102 self.osfamily = propertyNode.getAttribute("osfamily")
103 self.properties[self.osfamily] = OSFAMILY
104
105 elif propertyNode.hasAttribute("file"):
106 file = self.expandFromProperty(propertyNode.getAttribute("file"), propertyNode.getAttribute("default"))
107 self.getPropertiesFromFile(os.path.join(self.dirname, file))
108
109 elif propertyNode.hasAttribute("name"):
110 name = propertyNode.getAttribute("name")
111 value = self.expandFromEnvironent(propertyNode.getAttribute("value"), propertyNode.getAttribute("default"))
112 self.properties[name] = self.expandFromProperty(value, propertyNode.getAttribute("default"))
113
114 return self.properties
115
116
118 if os.path.exists(file):
119 try:
120 fp = open(file, "r")
121 except:
122 pass
123 else:
124 for line in fp.readlines():
125 regex = re.compile(PROPERTY_FILE, re.M)
126 if regex.search(line) is not None:
127 name = re.match(regex, line).group('name')
128 value = re.match(regex, line).group('value')
129 value = self.expandFromProperty(value, "")
130 self.properties[name.strip()] = value.strip()
131
132
134 regex = re.compile(PROPERTY_EXPAND_ENV%self.environment, re.M)
135 while regex.search(value) is not None:
136 matches = regex.findall(value)
137 for m in matches:
138 try:
139 insert = os.environ[m[1]]
140 except :
141 insert = default
142 value = value.replace(m[0], insert)
143 return value
144
145
147 regex = re.compile(PROPERTY_EXPAND, re.M)
148 while regex.search(value) is not None:
149 matches = regex.findall(value)
150 for m in matches:
151 try:
152 insert = self.properties[m[1]]
153 except :
154 insert = default
155 value = value.replace(m[0], insert)
156 return value
157
158
160 try:
161 runnerNodeList = self.root.getElementsByTagName('runner')[0]
162 return [runnerNodeList.getAttribute('classname'), runnerNodeList.getAttribute('module')]
163 except:
164 return DEFAULT_RUNNER
165
166
186
187
189 writersNodeList = self.root.getElementsByTagName('writers')
190 if writersNodeList == []: return [DEFAULT_WRITER]
191
192 try:
193 writers = []
194 writerNodeList = writersNodeList[0].getElementsByTagName('writer')
195 if writerNodeList != []:
196 for writerNode in writerNodeList:
197 try:
198 file = writerNode.getAttribute('file') if writerNode.hasAttribute('file') else None
199 writer = [writerNode.getAttribute('classname'), writerNode.getAttribute('module'), file, {}]
200 except:
201 pass
202 else:
203 propertyNodeList = writerNode.getElementsByTagName('property')
204 for propertyNode in propertyNodeList:
205 try:
206 name = propertyNode.getAttribute("name")
207 value = self.expandFromEnvironent(propertyNode.getAttribute("value"), propertyNode.getAttribute("default"))
208 writer[3][name] = self.expandFromProperty(value, propertyNode.getAttribute("default"))
209 except:
210 pass
211 writers.append(writer)
212 else:
213 writers.append(DEFAULT_WRITER)
214 return writers
215 except:
216 return [DEFAULT_WRITER]
217
218
220 pathNodeList = self.root.getElementsByTagName('path')
221
222 for pathNode in pathNodeList:
223 try:
224 value = pathNode.getAttribute("value")
225 relative = pathNode.getAttribute("relative")
226
227 if relative == "true": value = os.path.join(self.dirname, value)
228 sys.path.append(os.path.normpath(value))
229
230 except:
231 pass
232
233
235 f = open(self.xmlfile, 'w')
236 f.write(self.doc.toxml())
237 f.close()
238