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?, maker?, writers?, formatters?) >
29 <!ELEMENT property (#PCDATA)>
30 <!ELEMENT path (#PCDATA)>
31 <!ELEMENT runner (#PCDATA)>
32 <!ELEMENT maker (#PCDATA)>
33 <!ELEMENT formatters (formatter+) >
34 <!ELEMENT formatter (#PCDATA) >
35 <!ELEMENT writers (writer+) >
36 <!ELEMENT writer (property*) >
37 <!ATTLIST property root CDATA #IMPLIED>
38 <!ATTLIST property environment CDATA #IMPLIED>
39 <!ATTLIST property osfamily CDATA #IMPLIED>
40 <!ATTLIST property file CDATA #IMPLIED>
41 <!ATTLIST property name CDATA #IMPLIED>
42 <!ATTLIST property value CDATA #IMPLIED>
43 <!ATTLIST property default CDATA #IMPLIED>
44 <!ATTLIST path value CDATA #REQUIRED>
45 <!ATTLIST path relative CDATA #IMPLIED>
46 <!ATTLIST runner classname CDATA #REQUIRED>
47 <!ATTLIST runner module CDATA #REQUIRED>
48 <!ATTLIST maker classname CDATA #REQUIRED>
49 <!ATTLIST maker module CDATA #REQUIRED>
50 <!ATTLIST formatter name CDATA #REQUIRED>
51 <!ATTLIST formatter messagefmt CDATA #REQUIRED>
52 <!ATTLIST formatter datefmt CDATA #REQUIRED>
53 <!ATTLIST writer classname CDATA #REQUIRED>
54 <!ATTLIST writer module CDATA #REQUIRED>
55 <!ATTLIST writer file CDATA #IMPLIED>
56 ]>
57 '''
58
59 PROPERTY_EXPAND_ENV = "(?P<replace>\${%s.(?P<key>.*?)})"
60 PROPERTY_EXPAND = "(?P<replace>\${(?P<key>.*?)})"
61 PROPERTY_FILE = "(?P<name>^.*)=(?P<value>.*)$"
62
63
66 self.dirname = dirname
67 self.xmlfile = os.path.join(dirname, file)
68 self.rootdir = 'root'
69 self.environment = 'env'
70 self.osfamily = 'osfamily'
71 self.properties = {self.rootdir:self.dirname, self.osfamily:OSFAMILY}
72
73 if not os.path.exists(self.xmlfile):
74 raise Exception, "Unable to find supplied project file \"%s\"" % self.xmlfile
75
76 try:
77 self.doc = xml.dom.minidom.parse(self.xmlfile)
78 except:
79 raise Exception, sys.exc_info()[1]
80 else:
81 if self.doc.getElementsByTagName('pysysproject') == []:
82 raise Exception, "No <pysysproject> element supplied in project file"
83 else:
84 self.root = self.doc.getElementsByTagName('pysysproject')[0]
85
86
88 if self.doc: self.doc.unlink()
89
90
92 propertyNodeList = self.root.getElementsByTagName('property')
93
94 for propertyNode in propertyNodeList:
95 if propertyNode.hasAttribute("environment"):
96 self.environment = propertyNode.getAttribute("environment")
97
98 elif propertyNode.hasAttribute("root"):
99 self.properties.pop(self.rootdir, "")
100 self.rootdir = propertyNode.getAttribute("root")
101 self.properties[self.rootdir] = self.dirname
102
103 elif propertyNode.hasAttribute("osfamily"):
104 self.properties.pop(self.osfamily, "")
105 self.osfamily = propertyNode.getAttribute("osfamily")
106 self.properties[self.osfamily] = OSFAMILY
107
108 elif propertyNode.hasAttribute("file"):
109 file = self.expandFromProperty(propertyNode.getAttribute("file"), propertyNode.getAttribute("default"))
110 self.getPropertiesFromFile(os.path.join(self.dirname, file))
111
112 elif propertyNode.hasAttribute("name"):
113 name = propertyNode.getAttribute("name")
114 value = self.expandFromEnvironent(propertyNode.getAttribute("value"), propertyNode.getAttribute("default"))
115 self.properties[name] = self.expandFromProperty(value, propertyNode.getAttribute("default"))
116
117 return self.properties
118
119
121 if os.path.exists(file):
122 try:
123 fp = open(file, "r")
124 except:
125 pass
126 else:
127 for line in fp.readlines():
128 regex = re.compile(PROPERTY_FILE, re.M)
129 if regex.search(line) is not None:
130 name = re.match(regex, line).group('name')
131 value = re.match(regex, line).group('value')
132 value = self.expandFromProperty(value, "")
133 self.properties[name.strip()] = value.strip()
134
135
137 regex = re.compile(PROPERTY_EXPAND_ENV%self.environment, re.M)
138 while regex.search(value) is not None:
139 matches = regex.findall(value)
140 for m in matches:
141 try:
142 insert = os.environ[m[1]]
143 except :
144 insert = default
145 value = value.replace(m[0], insert)
146 return value
147
148
150 regex = re.compile(PROPERTY_EXPAND, re.M)
151 while regex.search(value) is not None:
152 matches = regex.findall(value)
153 for m in matches:
154 try:
155 insert = self.properties[m[1]]
156 except :
157 insert = default
158 value = value.replace(m[0], insert)
159 return value
160
161
163 try:
164 runnerNodeList = self.root.getElementsByTagName('runner')[0]
165 return [runnerNodeList.getAttribute('classname'), runnerNodeList.getAttribute('module')]
166 except:
167 return DEFAULT_RUNNER
168
169
171 try:
172 makerNodeList = self.root.getElementsByTagName('maker')[0]
173 return [makerNodeList.getAttribute('classname'), makerNodeList.getAttribute('module')]
174 except:
175 return DEFAULT_MAKER
176
177
197
198
200 writersNodeList = self.root.getElementsByTagName('writers')
201 if writersNodeList == []: return [DEFAULT_WRITER]
202
203 try:
204 writers = []
205 writerNodeList = writersNodeList[0].getElementsByTagName('writer')
206 if writerNodeList != []:
207 for writerNode in writerNodeList:
208 try:
209 file = writerNode.getAttribute('file') if writerNode.hasAttribute('file') else None
210 writer = [writerNode.getAttribute('classname'), writerNode.getAttribute('module'), file, {}]
211 except:
212 pass
213 else:
214 propertyNodeList = writerNode.getElementsByTagName('property')
215 for propertyNode in propertyNodeList:
216 try:
217 name = propertyNode.getAttribute("name")
218 value = self.expandFromEnvironent(propertyNode.getAttribute("value"), propertyNode.getAttribute("default"))
219 writer[3][name] = self.expandFromProperty(value, propertyNode.getAttribute("default"))
220 except:
221 pass
222 writers.append(writer)
223 else:
224 writers.append(DEFAULT_WRITER)
225 return writers
226 except:
227 return [DEFAULT_WRITER]
228
229
231 pathNodeList = self.root.getElementsByTagName('path')
232
233 for pathNode in pathNodeList:
234 try:
235 value = self.expandFromEnvironent(pathNode.getAttribute("value"), "")
236 value = self.expandFromProperty(value, "")
237 relative = pathNode.getAttribute("relative")
238
239 if relative == "true": value = os.path.join(self.dirname, value)
240 sys.path.append(os.path.normpath(value))
241
242 except:
243 pass
244
245
247 f = open(self.xmlfile, 'w')
248 f.write(self.doc.toxml())
249 f.close()
250