1
2
3 """
4 ::
5
6 Copyright 2010 Glencoe Software, Inc. All rights reserved.
7 Use is subject to license terms supplied in LICENSE.txt
8
9 """
10
11 """
12 Module which parses an icegrid XML file for configuration settings.
13
14 see ticket:800
15 see ticket:2213 - Replacing Java Preferences API
16 """
17
18 import os
19 import path
20 import time
21 import logging
22 import exceptions
23 import portalocker
24
25 import xml.dom.minidom
26
27 try:
28 from xml.etree.ElementTree import XML, Element, SubElement, Comment, ElementTree, tostring
29 except ImportError:
30 from elementtree.ElementTree import XML, Element, SubElement, Comment, ElementTree, tostring
31
32
34 """
35
36 """
37 KEY = "omero.config.version"
38 VERSION = "4.2.0"
39 INTERNAL = "__ACTIVE__"
40 DEFAULT = "omero.config.profile"
41 IGNORE = (KEY, DEFAULT)
42
43 - def __init__(self, filename, env_config = None, exclusive = True):
44 self.logger = logging.getLogger(self.__class__.__name__)
45 self.XML = None
46 self.env_config = env_config
47 self.filename = filename
48 self.source = open(filename, "a+")
49 self.lock = open("%s.lock" % filename, "a+")
50 self.exclusive = exclusive
51 if exclusive:
52 try:
53 portalocker.lock(self.lock, portalocker.LOCK_NB|portalocker.LOCK_EX)
54 except portalocker.LockException, le:
55 self.close()
56 raise
57
58 self.source.seek(0)
59 text = self.source.read()
60
61 if text:
62 self.XML = XML(text)
63 try:
64 self.version_check()
65 except:
66 self.close()
67 raise
68
69
70 if not self.XML:
71 default = self.default()
72 self.XML = Element("icegrid")
73 properties = SubElement(self.XML, "properties", id=self.INTERNAL)
74 _ = SubElement(properties, "property", name=self.DEFAULT, value=default)
75 _ = SubElement(properties, "property", name=self.KEY, value=self.VERSION)
76 properties = SubElement(self.XML, "properties", id=default)
77 _ = SubElement(properties, "property", name=self.KEY, value=self.VERSION)
78
87
93
95 """
96 Currently we are assuming that all blocks without a 4.2.0 version
97 are bogus. The configuration script when it generates an initial
98 config.xml will use prefs.class to parse the existing values and
99 immediately do the upgrade.
100 """
101 raise exceptions.Exception("Version mismatch: %s has %s" % (props.get("id"), version))
102
105
106 - def properties(self, id = None, filter_internal = False):
107
108 if not self.XML:
109 return None
110
111 props = self.XML.findall("./properties")
112 if id is None:
113 rv = list()
114 for x in props:
115 id = x.attrib["id"]
116 if filter_internal:
117 if id == self.INTERNAL:
118 continue
119 rv.append((id, x))
120 return rv
121 for p in props:
122 if "id" in p.attrib and p.attrib["id"] == id:
123 return p
124
132
134 if value:
135 self.env_config = value
136 if self.env_config:
137 return self.env_config
138 elif "OMERO_CONFIG" in os.environ:
139 return os.environ["OMERO_CONFIG"]
140 else:
141
142
143
144
145
146
147 return "default"
148
155
157 """
158 Creates a fresh <icegrid> block (removing any unwanted
159 intra-element whitespace) and overwrites the file on disk.
160 """
161 icegrid = Element("icegrid")
162 comment = Comment("\n".join(["\n",
163 "\tThis file was generated at %s by the OmeroConfig system.",
164 "\tDo not edit directly but see bin/omero config for details.",
165 "\tThis file may be included into your IceGrid application.",
166 "\n"]) % time.ctime())
167 icegrid.append(comment)
168
169
170
171 default = self.default()
172 internal = SubElement(icegrid, "properties", id=self.INTERNAL)
173 SubElement(internal, "property", name=self.DEFAULT, value=default)
174 SubElement(internal, "property", name=self.KEY, value=self.VERSION)
175 to_copy = self.properties(default)
176 if to_copy is not None:
177 for x in to_copy.getchildren():
178 if x.get("name") != self.DEFAULT and x.get("name") != self.KEY:
179 SubElement(internal, "property", x.attrib)
180 else:
181
182 properties = SubElement(icegrid, "properties", id=default)
183 SubElement(properties, "property", name=self.KEY, value=self.VERSION)
184
185 prop_list = self.properties(None, True)
186 for k, p in prop_list:
187 self.clear_text(p)
188 icegrid.append(p)
189 self.source.seek(0)
190 self.source.truncate()
191 self.source.write(self.element_to_xml(icegrid))
192 self.source.flush()
193
195 try:
196
197
198
199 if self.XML:
200 self.save()
201 finally:
202 try:
203 self.source.close()
204 finally:
205 self.lock.close()
206
208
209 if c is None:
210 return {}
211
212 rv = dict()
213 props = c.findall("./property")
214 for p in props:
215 if "name" in p.attrib:
216 rv[p.attrib["name"]] = p.attrib.get("value", "")
217 return rv
218
219 - def dict_to_text(self, parsed = None):
220
221 if parsed is None:
222 return
223
224 rv = ""
225 for k, v in parsed.items():
226 rv += "%s=%s" % (k, v)
227 return rv
228
230 string = tostring(elem, 'utf-8')
231 return xml.dom.minidom.parseString(string).toprettyxml(" ", "\n", None)
232
233 - def clear_text(self, p):
234 """
235 To prevent the accumulation of text outside of elements (including whitespace)
236 we walk the given element and remove tail from it and it's children.
237 """
238 p.tail = ""
239 p.text = ""
240 for p2 in p.getchildren():
241 self.clear_text(p2)
242
243
244
245
248
251
254
267
277