|
1 # |
|
2 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 # All rights reserved. |
|
4 # This component and the accompanying materials are made available |
|
5 # under the terms of "Eclipse Public License v1.0" |
|
6 # which accompanies this distribution, and is available |
|
7 # at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 # |
|
9 # Initial Contributors: |
|
10 # Nokia Corporation - initial contribution. |
|
11 # |
|
12 # Contributors: |
|
13 # |
|
14 # Description: |
|
15 # |
|
16 import re |
|
17 import logging |
|
18 import xml.parsers.expat |
|
19 try: |
|
20 from cElementTree import ElementTree |
|
21 except ImportError: |
|
22 try: |
|
23 from elementtree import ElementTree |
|
24 except ImportError: |
|
25 try: |
|
26 from xml.etree import cElementTree as ElementTree |
|
27 except ImportError: |
|
28 from xml.etree import ElementTree |
|
29 |
|
30 """ cone specific imports """ |
|
31 from cone.public import persistence, exceptions, api, utils, container |
|
32 from cone.confml import model |
|
33 |
|
34 CONFIGURATION_NAMESPACES = ["http://www.s60.com/xml/confml/2","http://www.s60.com/xml/confml/1"] |
|
35 INCLUDE_NAMESPACES = ["http://www.w3.org/2001/XInclude","http://www.w3.org/2001/xinclude"] |
|
36 XLINK_NAMESPACES = ["http://www.w3.org/1999/xlink"] |
|
37 SCHEMA_NAMESPACES = ["http://www.w3.org/2001/XMLSchema"] |
|
38 CV_NAMESPACE = {"http://www.nokia.com/xml/cpf-id/1": "cv"} |
|
39 MODEL = model |
|
40 |
|
41 def dumps(obj, indent=True): |
|
42 etree = ConfmlWriter().dumps(obj) |
|
43 if indent: |
|
44 persistence.indent(etree) |
|
45 return ElementTree.tostring(etree) |
|
46 |
|
47 def loads(xml): |
|
48 return ConfmlReader().loads(xml) |
|
49 |
|
50 |
|
51 |
|
52 class ConfmlWriter(persistence.ConeWriter): |
|
53 """ |
|
54 """ |
|
55 def dumps(self, obj): |
|
56 """ |
|
57 @param obj: The object |
|
58 """ |
|
59 """ Make sure that the object is mapped to an object in this model """ |
|
60 mobj = obj._get_mapper('confml').map_object(obj) |
|
61 writer = get_writer_for_class(mobj.__class__.__name__) |
|
62 return writer.dumps(obj) |
|
63 |
|
64 class ConfmlReader(persistence.ConeReader): |
|
65 """ |
|
66 """ |
|
67 def loads(self, xmlstr): |
|
68 """ |
|
69 @param xml: The xml which to read. reads only the first object. |
|
70 """ |
|
71 reader = get_reader_for_elem("configuration") |
|
72 etree = utils.etree.fromstring(xmlstr) |
|
73 return reader.loads(etree) |
|
74 |
|
75 |
|
76 class ConfigurationWriter(ConfmlWriter): |
|
77 """ |
|
78 Writes a single Configuration project confml file. |
|
79 """ |
|
80 @classmethod |
|
81 def supported_class(cls, classname): |
|
82 """ |
|
83 Class method to determine if this ConfmlWriter supports writing |
|
84 of the given class name |
|
85 """ |
|
86 if classname=="Configuration" or \ |
|
87 classname=="ConfmlConfiguration" : |
|
88 return True |
|
89 else: |
|
90 return False |
|
91 |
|
92 def __init__(self): |
|
93 self.configuration_namespace = CONFIGURATION_NAMESPACES[0] |
|
94 self.include_namespace = INCLUDE_NAMESPACES[0] |
|
95 self.xlink_namespace = XLINK_NAMESPACES[0] |
|
96 self.schema_namespace = SCHEMA_NAMESPACES[0] |
|
97 |
|
98 def dumps(self,obj,indent=True): |
|
99 elem = ElementTree.Element("configuration") |
|
100 if self.configuration_namespace: |
|
101 elem.set("xmlns",self.configuration_namespace) |
|
102 if self.include_namespace: |
|
103 elem.set("xmlns:xi",self.include_namespace) |
|
104 if self.include_namespace: |
|
105 elem.set("xmlns:xlink",self.xlink_namespace) |
|
106 if self.schema_namespace: |
|
107 elem.set("xmlns:xs",self.schema_namespace) |
|
108 elem.set("name",obj.get_name()) |
|
109 for child in obj._objects(): |
|
110 """ Make sure that the object is mapped to an object in this model """ |
|
111 mobj = child._get_mapper('confml').map_object(child) |
|
112 writer = get_writer_for_class(mobj.__class__.__name__) |
|
113 childelem = writer.dumps(child) |
|
114 elem.append(childelem) |
|
115 return elem |
|
116 |
|
117 |
|
118 class ConfigurationReader(ConfmlReader): |
|
119 """ |
|
120 Parses a single CPF configuration project root confml file. Parses the XInclude statements to |
|
121 find out the layers inside the project |
|
122 """ |
|
123 @classmethod |
|
124 def supported_elem(cls, elemname, parent=None): |
|
125 """ |
|
126 Class method to determine if this ConfmlWriter supports writing |
|
127 of the given elem name |
|
128 """ |
|
129 if elemname=="configuration": |
|
130 return True |
|
131 else: |
|
132 return False |
|
133 |
|
134 def __init__(self): |
|
135 self.configuration_namespaces = CONFIGURATION_NAMESPACES |
|
136 self.include_namespaces = INCLUDE_NAMESPACES |
|
137 self.schema_namespaces = SCHEMA_NAMESPACES |
|
138 |
|
139 def loads(self, etree): |
|
140 configuration = model.ConfmlConfiguration("") |
|
141 configuration.set_name(etree.get("name") or 'unknown') |
|
142 configuration.set_ref(etree.get("name") or 'unknown') |
|
143 for elem in etree.getchildren(): |
|
144 # At the moment we ignore the namespace of elements |
|
145 (namespace,elemname) = get_elemname(elem.tag) |
|
146 try: |
|
147 reader = get_reader_for_elem(elemname) |
|
148 obj = reader.loads(elem) |
|
149 if obj: |
|
150 configuration.add(obj) |
|
151 except exceptions.ConePersistenceError,e: |
|
152 logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e)) |
|
153 continue |
|
154 return configuration |
|
155 |
|
156 |
|
157 class MetaWriter(ConfmlWriter): |
|
158 @classmethod |
|
159 def supported_class(cls, classname): |
|
160 """ |
|
161 Class method to determine if this ConfmlWriter supports writing |
|
162 of the given class name |
|
163 """ |
|
164 if classname=="ConfmlMeta": |
|
165 return True |
|
166 else: |
|
167 return False |
|
168 |
|
169 def dumps(self, obj): |
|
170 """ |
|
171 @param obj: The Configuration object |
|
172 """ |
|
173 |
|
174 elem = ElementTree.Element("meta") |
|
175 for metaproperty in obj: |
|
176 prefix = CV_NAMESPACE.get(metaproperty.ns, "") |
|
177 if prefix != "": |
|
178 #Including namespace to metadata element as well |
|
179 elem.set(("xmlns:%s" % prefix), metaproperty.ns) |
|
180 childelem = ElementTree.Element(prefix + ":" + metaproperty.tag) |
|
181 else: |
|
182 childelem = ElementTree.Element(metaproperty.tag) |
|
183 if metaproperty.value != None: |
|
184 childelem.text = metaproperty.value |
|
185 for attr in metaproperty.attrs: |
|
186 childelem.set(attr, metaproperty.attrs[attr]) |
|
187 elem.append(childelem) |
|
188 return elem |
|
189 |
|
190 |
|
191 class MetaReader(ConfmlReader): |
|
192 @classmethod |
|
193 def supported_elem(cls, elemname, parent=None): |
|
194 """ |
|
195 Class method to determine if this ConfmlWriter supports reading |
|
196 of the given elem name |
|
197 """ |
|
198 if elemname=="meta": |
|
199 return True |
|
200 else: |
|
201 return False |
|
202 |
|
203 def loads(self,etree): |
|
204 metaelem = model.ConfmlMeta() |
|
205 for elem in etree.getchildren(): |
|
206 (namespace,elemname) = get_elemname(elem.tag) |
|
207 attributes = {} |
|
208 for key in elem.keys(): |
|
209 attributes[key] = elem.get(key) |
|
210 |
|
211 metaprop = model.ConfmlMetaProperty(elemname, elem.text, namespace, attrs=attributes) |
|
212 metaelem.append(metaprop) |
|
213 return metaelem |
|
214 |
|
215 |
|
216 class DescWriter(ConfmlWriter): |
|
217 """ |
|
218 """ |
|
219 @classmethod |
|
220 def supported_class(cls, classname): |
|
221 """ |
|
222 Class method to determine if this ConfmlWriter supports writing |
|
223 of the given class name |
|
224 """ |
|
225 if classname=="ConfmlDescription": |
|
226 return True |
|
227 else: |
|
228 return False |
|
229 |
|
230 def dumps(self, obj): |
|
231 """ |
|
232 @param obj: The Configuration object |
|
233 """ |
|
234 elem = ElementTree.Element('desc') |
|
235 elem.text = obj.text |
|
236 return elem |
|
237 |
|
238 |
|
239 class DescReader(ConfmlReader): |
|
240 @classmethod |
|
241 def supported_elem(cls, elemname, parent=None): |
|
242 """ |
|
243 Class method to determine if this ConfmlReader supports reading |
|
244 of the given elem name |
|
245 """ |
|
246 if elemname=="desc": |
|
247 return True |
|
248 else: |
|
249 return False |
|
250 |
|
251 def loads(self,elem): |
|
252 desc = model.ConfmlDescription(elem.text) |
|
253 return desc |
|
254 |
|
255 class ConfigurationProxyWriter(ConfmlWriter): |
|
256 """ |
|
257 """ |
|
258 @classmethod |
|
259 def supported_class(cls, classname): |
|
260 """ |
|
261 Class method to determine if this ConfmlWriter supports writing |
|
262 of the given class name |
|
263 """ |
|
264 if classname=="ConfigurationProxy": |
|
265 return True |
|
266 else: |
|
267 return False |
|
268 |
|
269 def dumps(self, obj): |
|
270 """ |
|
271 @param obj: The Configuration object |
|
272 """ |
|
273 elem = self.to_include(obj.path) |
|
274 return elem |
|
275 |
|
276 def to_include(self,include): |
|
277 elem = ElementTree.Element("xi:include",{"href":include}) |
|
278 return elem |
|
279 |
|
280 class ConfigurationProxyReader(ConfmlReader): |
|
281 """ |
|
282 """ |
|
283 @classmethod |
|
284 def supported_elem(cls, elemname, parent=None): |
|
285 """ |
|
286 Class method to determine if this ConfmlWriter supports reading |
|
287 of the given elem name |
|
288 """ |
|
289 if elemname=="include": |
|
290 return True |
|
291 else: |
|
292 return False |
|
293 |
|
294 def loads(self, elem): |
|
295 """ |
|
296 @param elem: The xml include elem |
|
297 """ |
|
298 |
|
299 return api.ConfigurationProxy(self.parse_include(elem)) |
|
300 |
|
301 def parse_include(self,include): |
|
302 #print "Found include %s" % include.get('href').replace('#/','') |
|
303 return include.get('href').replace('#/','') |
|
304 |
|
305 |
|
306 class FeatureWriter(ConfmlWriter): |
|
307 @classmethod |
|
308 def supported_class(cls, classname): |
|
309 """ |
|
310 Class method to determine if this ConfmlWriter supports writing |
|
311 of the given class name |
|
312 """ |
|
313 if classname=="ConfmlFeature" or \ |
|
314 classname=="Feature": |
|
315 return True |
|
316 else: |
|
317 return False |
|
318 |
|
319 def dumps(self, obj): |
|
320 """ |
|
321 @param obj: The Configuration object |
|
322 """ |
|
323 elem = ElementTree.Element('feature', |
|
324 {'ref' : obj.get_ref(), |
|
325 'name' : obj.get_name()}) |
|
326 if obj.get_type(): |
|
327 elem.set('type', obj.get_type()) |
|
328 for child in obj._objects(): |
|
329 """ Make sure that the object is mapped to an object in this model """ |
|
330 mobj = child._get_mapper('confml').map_object(child) |
|
331 writer = get_writer_for_class(mobj.__class__.__name__) |
|
332 childelem = writer.dumps(child) |
|
333 if childelem != None: |
|
334 elem.append(childelem) |
|
335 return elem |
|
336 |
|
337 |
|
338 class FeatureReader(ConfmlReader): |
|
339 """ |
|
340 """ |
|
341 @classmethod |
|
342 def supported_elem(cls, elemname, parent=None): |
|
343 """ |
|
344 Class method to determine if this ConfmlWriter supports reading |
|
345 of the given elem name |
|
346 """ |
|
347 if elemname=="feature": |
|
348 return True |
|
349 else: |
|
350 return False |
|
351 |
|
352 def loads(self, elem): |
|
353 """ |
|
354 @param elem: The xml include elem |
|
355 """ |
|
356 type = elem.get('type') |
|
357 if type == 'sequence': |
|
358 feature = api.FeatureSequence(elem.get('ref')) |
|
359 else: |
|
360 feature = model.ConfmlFeature(elem.get('ref')) |
|
361 if elem.get('name'): |
|
362 feature.set_name(elem.get('name')) |
|
363 feature.set_type(type) |
|
364 for elem in elem.getchildren(): |
|
365 # At the moment we ignore the namespace of elements |
|
366 (namespace,elemname) = get_elemname(elem.tag) |
|
367 try: |
|
368 reader = get_reader_for_elem(elemname) |
|
369 obj = reader.loads(elem) |
|
370 feature.add(obj) |
|
371 except exceptions.ConePersistenceError,e: |
|
372 logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e)) |
|
373 continue |
|
374 return feature |
|
375 |
|
376 |
|
377 class OptionWriter(ConfmlWriter): |
|
378 @classmethod |
|
379 def supported_class(cls, classname): |
|
380 """ |
|
381 Class method to determine if this ConfmlWriter supports writing |
|
382 of the given class name |
|
383 """ |
|
384 if classname=="Option": |
|
385 return True |
|
386 else: |
|
387 return False |
|
388 |
|
389 def dumps(self, obj): |
|
390 """ |
|
391 @param obj: The Option object |
|
392 """ |
|
393 |
|
394 objdict = {} |
|
395 if obj.get_name() is not None: objdict['name'] = obj.get_name() |
|
396 if obj.get_value() is not None: objdict['value'] = obj.get_value() |
|
397 if obj.map is not None: objdict['map'] = obj.map |
|
398 if obj.relevant is not None: objdict['relevant'] = obj.relevant |
|
399 elem = ElementTree.Element('option', objdict) |
|
400 |
|
401 return elem |
|
402 |
|
403 |
|
404 class OptionReader(ConfmlReader): |
|
405 """ |
|
406 """ |
|
407 @classmethod |
|
408 def supported_elem(cls, elemname, parent=None): |
|
409 """ |
|
410 Class method to determine if this ConfmlWriter supports reading |
|
411 of the given elem name |
|
412 """ |
|
413 if elemname=="option": |
|
414 return True |
|
415 else: |
|
416 return False |
|
417 |
|
418 def loads(self, elem): |
|
419 """ |
|
420 @param elem: The xml include elem |
|
421 """ |
|
422 name = elem.get('name') |
|
423 value = elem.get('value') |
|
424 optmap = elem.get('map') |
|
425 if value == None and optmap == None: |
|
426 logging.getLogger('cone').warning("Encountered option with no value") |
|
427 option = None |
|
428 else: |
|
429 option = api.Option(name, value, map=optmap, relevant=elem.get('relevant')) |
|
430 return option |
|
431 |
|
432 |
|
433 class IconWriter(ConfmlWriter): |
|
434 @classmethod |
|
435 def supported_class(cls, classname): |
|
436 """ |
|
437 Class method to determine if this ConfmlWriter supports writing |
|
438 of the given class name |
|
439 """ |
|
440 if classname=="ConfmlIcon": |
|
441 return True |
|
442 else: |
|
443 return False |
|
444 |
|
445 def dumps(self, obj): |
|
446 """ |
|
447 @param obj: The Option object |
|
448 """ |
|
449 elem = ElementTree.Element('icon', |
|
450 {'xlink:href' : obj.href}) |
|
451 return elem |
|
452 |
|
453 |
|
454 class IconReader(ConfmlReader): |
|
455 """ |
|
456 """ |
|
457 @classmethod |
|
458 def supported_elem(cls, elemname, parent=None): |
|
459 """ |
|
460 Class method to determine if this ConfmlWriter supports reading |
|
461 of the given elem name |
|
462 """ |
|
463 if elemname=="icon": |
|
464 return True |
|
465 else: |
|
466 return False |
|
467 |
|
468 def loads(self, elem): |
|
469 """ |
|
470 @param elem: The xml include elem |
|
471 """ |
|
472 href = elem.get('{%s}href' % XLINK_NAMESPACES[0]) |
|
473 obj = model.ConfmlIcon(href) |
|
474 return obj |
|
475 |
|
476 |
|
477 class PropertyWriter(ConfmlWriter): |
|
478 @classmethod |
|
479 def supported_class(cls, classname): |
|
480 """ |
|
481 Class method to determine if this ConfmlWriter supports writing |
|
482 of the given class name |
|
483 """ |
|
484 if classname=="ConfmlProperty": |
|
485 return True |
|
486 else: |
|
487 return False |
|
488 |
|
489 def dumps(self, obj): |
|
490 """ |
|
491 @param obj: The Option object |
|
492 """ |
|
493 elem = ElementTree.Element('property') |
|
494 if obj.name != None: |
|
495 elem.set('name', obj.name) |
|
496 if obj.value != None: |
|
497 elem.set('value', obj.value) |
|
498 if obj.unit != None: |
|
499 elem.set('unit', obj.unit) |
|
500 return elem |
|
501 |
|
502 |
|
503 class PropertyReader(ConfmlReader): |
|
504 """ |
|
505 """ |
|
506 @classmethod |
|
507 def supported_elem(cls, elemname, parent=None): |
|
508 """ |
|
509 Class method to determine if this ConfmlWriter supports reading |
|
510 of the given elem name |
|
511 """ |
|
512 if elemname=="property": |
|
513 return True |
|
514 else: |
|
515 return False |
|
516 |
|
517 def loads(self, elem): |
|
518 """ |
|
519 @param elem: The xml include elem |
|
520 """ |
|
521 option = model.ConfmlProperty(name=elem.get('name'),value=elem.get('value'), unit=elem.get('unit')) |
|
522 return option |
|
523 |
|
524 |
|
525 class XmlSchemaFacetWriter(ConfmlWriter): |
|
526 MAPPING = {'ConfmlLength' : 'xs:length', |
|
527 'ConfmlMinLength' : 'xs:minLength', |
|
528 'ConfmlMaxLength' : 'xs:maxLength', |
|
529 'ConfmlMinInclusive' : 'xs:minInclusive', |
|
530 'ConfmlMaxInclusive' : 'xs:maxInclusive', |
|
531 'ConfmlMinExclusive' : 'xs:minExclusive', |
|
532 'ConfmlMaxExclusive' : 'xs:maxExclusive', |
|
533 'ConfmlPattern' : 'xs:pattern', |
|
534 'ConfmlTotalDigits' : 'xs:totalDigits'} |
|
535 |
|
536 @classmethod |
|
537 def supported_class(cls, classname): |
|
538 return classname in cls.MAPPING |
|
539 |
|
540 def dumps(self, obj): |
|
541 """ |
|
542 @param obj: The facet object |
|
543 """ |
|
544 |
|
545 classname = obj.__class__.__name__ |
|
546 elem = ElementTree.Element(self.MAPPING[classname]) |
|
547 if obj.value != None: |
|
548 elem.set('value', str(obj.value)) |
|
549 return elem |
|
550 |
|
551 class XmlSchemaFacetReader(ConfmlReader): |
|
552 MAPPING = {'length' : model.ConfmlLength, |
|
553 'minLength' : model.ConfmlMinLength, |
|
554 'maxLength' : model.ConfmlMaxLength, |
|
555 'minInclusive' : model.ConfmlMinInclusive, |
|
556 'maxInclusive' : model.ConfmlMaxInclusive, |
|
557 'minExclusive' : model.ConfmlMinExclusive, |
|
558 'maxExclusive' : model.ConfmlMaxExclusive, |
|
559 'pattern' : model.ConfmlPattern, |
|
560 'totalDigits' : model.ConfmlTotalDigits} |
|
561 |
|
562 @classmethod |
|
563 def supported_elem(cls, elemname, parent=None): |
|
564 """ |
|
565 Class method to determine if this ConfmlWriter supports reading |
|
566 of the given elem name |
|
567 """ |
|
568 return elemname in cls.MAPPING |
|
569 |
|
570 def loads(self, elem): |
|
571 """ |
|
572 @param elem: The XML schema facet element |
|
573 """ |
|
574 elem_name = utils.xml.split_tag_namespace(elem.tag)[1] |
|
575 facet_class = self.MAPPING[elem_name] |
|
576 obj = facet_class(elem.get('value')) |
|
577 return obj |
|
578 |
|
579 |
|
580 class DataWriter(ConfmlWriter): |
|
581 @classmethod |
|
582 def supported_class(cls, classname): |
|
583 """ |
|
584 Class method to determine if this ConfmlWriter supports writing |
|
585 of the given class name |
|
586 """ |
|
587 if classname=="Data": |
|
588 return True |
|
589 if classname=="DataContainer": |
|
590 return True |
|
591 else: |
|
592 return False |
|
593 |
|
594 def dumps(self, obj): |
|
595 """ |
|
596 @param obj: The Data object |
|
597 """ |
|
598 # Create a data hierarchy of the |
|
599 elem = ElementTree.Element(obj.get_ref()) |
|
600 if hasattr(obj,'get_value') and obj.get_value() and not obj.get_map(): |
|
601 elem.text = obj.get_value() |
|
602 elif hasattr(obj,'get_map') and obj.get_map(): |
|
603 elem.set('map', obj.get_map()) |
|
604 if hasattr(obj,'template') and obj.template == True: |
|
605 elem.set('template','true') |
|
606 if hasattr(obj,'policy') and obj.policy != '': |
|
607 elem.set('extensionPolicy',obj.policy) |
|
608 for child in obj._objects(): |
|
609 writer = DataWriter() |
|
610 childelem = writer.dumps(child) |
|
611 if childelem != None: |
|
612 elem.append(childelem) |
|
613 return elem |
|
614 |
|
615 |
|
616 class DataReader(ConfmlReader): |
|
617 """ |
|
618 """ |
|
619 @classmethod |
|
620 def supported_elem(cls, elemname, parent=None): |
|
621 """ |
|
622 Class method to determine if this ConfmlWriter supports reading |
|
623 of the given elem name |
|
624 """ |
|
625 if elemname=="data": |
|
626 return True |
|
627 else: |
|
628 return False |
|
629 |
|
630 def loads(self, elem): |
|
631 """ |
|
632 @param elem: The xml include elem |
|
633 """ |
|
634 |
|
635 (namespace,elemname) = get_elemname(elem.tag) |
|
636 obj = api.DataContainer(elemname, container=True) |
|
637 for elem in elem.getchildren(): |
|
638 try: |
|
639 reader = ElemReader(attr='data') |
|
640 childobj = reader.loads(elem) |
|
641 obj.add(childobj) |
|
642 except exceptions.ConePersistenceError,e: |
|
643 logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e)) |
|
644 continue |
|
645 return obj |
|
646 |
|
647 |
|
648 class ViewWriter(ConfmlWriter): |
|
649 @classmethod |
|
650 def supported_class(cls, classname): |
|
651 """ |
|
652 Class method to determine if this ConfmlWriter supports writing |
|
653 of the given class name |
|
654 """ |
|
655 if classname=="View" or \ |
|
656 classname=="ConfmlView": |
|
657 return True |
|
658 else: |
|
659 return False |
|
660 |
|
661 def dumps(self, obj): |
|
662 """ |
|
663 @param obj: The Configuration object |
|
664 """ |
|
665 elem = ElementTree.Element('view', |
|
666 {'id' : obj.get_ref(), |
|
667 'name' : obj.get_name()}) |
|
668 for child in obj._objects(): |
|
669 """ Make sure that the object is mapped to an object in this model """ |
|
670 mobj = child._get_mapper('confml').map_object(child) |
|
671 writer = get_writer_for_class(mobj.__class__.__name__) |
|
672 childelem = writer.dumps(child) |
|
673 if childelem != None: |
|
674 elem.append(childelem) |
|
675 return elem |
|
676 |
|
677 |
|
678 class ViewReader(ConfmlReader): |
|
679 """ |
|
680 """ |
|
681 @classmethod |
|
682 def supported_elem(cls, elemname, parent=None): |
|
683 """ |
|
684 Class method to determine if this ConfmlWriter supports reading |
|
685 of the given elem name |
|
686 """ |
|
687 if elemname=="view": |
|
688 return True |
|
689 else: |
|
690 return False |
|
691 |
|
692 def loads(self, elem): |
|
693 """ |
|
694 @param elem: The xml include elem |
|
695 """ |
|
696 vid = elem.get('id') |
|
697 name = elem.get('name') |
|
698 view = model.ConfmlView(name, id=vid) |
|
699 for elem in elem.getchildren(): |
|
700 # At the moment we ignore the namespace of elements |
|
701 (namespace,elemname) = get_elemname(elem.tag) |
|
702 try: |
|
703 reader = get_reader_for_elem(elemname) |
|
704 obj = reader.loads(elem) |
|
705 view.add(obj) |
|
706 except exceptions.ConePersistenceError,e: |
|
707 logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e)) |
|
708 continue |
|
709 return view |
|
710 |
|
711 |
|
712 class GroupWriter(ConfmlWriter): |
|
713 @classmethod |
|
714 def supported_class(cls, classname): |
|
715 """ |
|
716 Class method to determine if this ConfmlWriter supports writing |
|
717 of the given class name |
|
718 """ |
|
719 if classname=="Group" or classname=="ConfmlGroup": |
|
720 return True |
|
721 else: |
|
722 return False |
|
723 |
|
724 def dumps(self, obj): |
|
725 """ |
|
726 @param obj: The Configuration object |
|
727 """ |
|
728 elem = ElementTree.Element('group', |
|
729 {'name' : obj.get_name()}) |
|
730 for child in obj._objects(): |
|
731 """ Make sure that the object is mapped to an object in this model """ |
|
732 mobj = child._get_mapper('confml').map_object(child) |
|
733 writer = get_writer_for_class(mobj.__class__.__name__) |
|
734 childelem = writer.dumps(child) |
|
735 if childelem != None: |
|
736 elem.append(childelem) |
|
737 return elem |
|
738 |
|
739 |
|
740 class GroupReader(ConfmlReader): |
|
741 """ |
|
742 """ |
|
743 @classmethod |
|
744 def supported_elem(cls, elemname, parent=None): |
|
745 """ |
|
746 Class method to determine if this ConfmlWriter supports reading |
|
747 of the given elem name |
|
748 """ |
|
749 if elemname=='group': |
|
750 return True |
|
751 else: |
|
752 return False |
|
753 |
|
754 def loads(self, elem): |
|
755 """ |
|
756 @param elem: The xml include elem |
|
757 """ |
|
758 gname = elem.get('name') |
|
759 gref = utils.resourceref.to_dref(gname).replace('.','_') |
|
760 group = model.ConfmlGroup(gref, name=gname) |
|
761 for elem in elem.getchildren(): |
|
762 # At the moment we ignore the namespace of elements |
|
763 (namespace,elemname) = get_elemname(elem.tag) |
|
764 try: |
|
765 reader = get_reader_for_elem(elemname, 'group') |
|
766 obj = reader.loads(elem) |
|
767 if obj != None: |
|
768 group.add(obj) |
|
769 except exceptions.ConePersistenceError,e: |
|
770 logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e)) |
|
771 continue |
|
772 return group |
|
773 |
|
774 |
|
775 class GroupSettingWriter(ConfmlWriter): |
|
776 """ |
|
777 """ |
|
778 @classmethod |
|
779 def supported_class(cls, classname): |
|
780 """ |
|
781 Class method to determine if this ConfmlWriter supports writing |
|
782 of the given class name |
|
783 """ |
|
784 if classname=="FeatureLink": |
|
785 return True |
|
786 else: |
|
787 return False |
|
788 |
|
789 def dumps(self, obj): |
|
790 """ |
|
791 @param obj: The Configuration object |
|
792 """ |
|
793 ref = obj.fqr.replace('.','/') |
|
794 elem = ElementTree.Element('setting', |
|
795 {'ref' : ref}) |
|
796 return elem |
|
797 |
|
798 class GroupSettingReader(ConfmlReader): |
|
799 """ |
|
800 """ |
|
801 @classmethod |
|
802 def supported_elem(cls, elemname, parent=None): |
|
803 """ |
|
804 Class method to determine if this ConfmlWriter supports reading |
|
805 of the given elem name |
|
806 """ |
|
807 if elemname=='setting' and parent=='group': |
|
808 return True |
|
809 else: |
|
810 return False |
|
811 |
|
812 def loads(self, elem): |
|
813 """ |
|
814 @param elem: The xml include elem |
|
815 """ |
|
816 ref = elem.get('ref') or '' |
|
817 ref = ref.replace('/','.') |
|
818 return api.FeatureLink(ref) |
|
819 |
|
820 |
|
821 |
|
822 class ConfmlSettingWriter(ConfmlWriter): |
|
823 @classmethod |
|
824 def supported_class(cls, classname): |
|
825 """ |
|
826 Class method to determine if this ConfmlWriter supports writing |
|
827 of the given class name |
|
828 """ |
|
829 if classname=="ConfmlSetting" or \ |
|
830 classname=="ConfmlStringSetting" or \ |
|
831 classname=="ConfmlIntSetting" or \ |
|
832 classname=="ConfmlRealSetting" or \ |
|
833 classname=="ConfmlBooleanSetting" or \ |
|
834 classname=="ConfmlSelectionSetting" or \ |
|
835 classname=="ConfmlMultiSelectionSetting" or \ |
|
836 classname=="ConfmlDateSetting" or \ |
|
837 classname=="ConfmlTimeSetting" or \ |
|
838 classname=="ConfmlDateTimeSetting" or \ |
|
839 classname=="ConfmlDurationSetting" or \ |
|
840 classname=="ConfmlFileSetting" or \ |
|
841 classname=="ConfmlFolderSetting" or \ |
|
842 classname=="FeatureSequence" or \ |
|
843 classname=="ConfmlSequenceSetting": |
|
844 return True |
|
845 else: |
|
846 return False |
|
847 |
|
848 def dumps(self, obj): |
|
849 """ |
|
850 @param obj: The Configuration object |
|
851 """ |
|
852 elem = ElementTree.Element('setting', |
|
853 {'ref' : obj.get_ref(), |
|
854 'name' : obj.get_name()}) |
|
855 if obj.type: |
|
856 elem.set('type', obj.get_type()) |
|
857 if hasattr(obj,'minOccurs'): |
|
858 elem.set('minOccurs', str(obj.minOccurs)) |
|
859 if hasattr(obj,'maxOccurs'): |
|
860 elem.set('maxOccurs', str(obj.maxOccurs)) |
|
861 if hasattr(obj,'readOnly') and obj.readOnly != None: |
|
862 elem.set('readOnly', str(obj.readOnly).lower()) |
|
863 if hasattr(obj,'required') and obj.required != None: |
|
864 elem.set('required', str(obj.required).lower()) |
|
865 if hasattr(obj,'constraint') and obj.constraint != None: |
|
866 elem.set('constraint', obj.constraint) |
|
867 if hasattr(obj,'relevant') and obj.relevant != None: |
|
868 elem.set('relevant', obj.relevant) |
|
869 if hasattr(obj,'mapKey') and obj.mapKey is not None: |
|
870 elem.set('mapKey', str(obj.mapKey)) |
|
871 if hasattr(obj,'mapValue') and obj.mapValue is not None: |
|
872 elem.set('mapValue', str(obj.mapValue)) |
|
873 |
|
874 for child in obj._objects(): |
|
875 """ Make sure that the object is mapped to an object in this model """ |
|
876 mobj = child._get_mapper('confml').map_object(child) |
|
877 writer = get_writer_for_class(mobj.__class__.__name__) |
|
878 childelem = writer.dumps(child) |
|
879 if childelem != None: |
|
880 elem.append(childelem) |
|
881 return elem |
|
882 |
|
883 |
|
884 class ConfmlSettingReader(ConfmlReader): |
|
885 """ |
|
886 """ |
|
887 @classmethod |
|
888 def supported_elem(cls, elemname, parent=None): |
|
889 """ |
|
890 Class method to determine if this ConfmlWriter supports reading |
|
891 of the given elem name |
|
892 """ |
|
893 if parent and not (parent=='feature' or parent=='setting'): |
|
894 return False |
|
895 if elemname=='setting': |
|
896 return True |
|
897 else: |
|
898 return False |
|
899 |
|
900 def loads(self, elem): |
|
901 """ |
|
902 @param elem: The xml include elem |
|
903 """ |
|
904 typedef = elem.get('type') |
|
905 if typedef == 'sequence': |
|
906 map_key = elem.get('mapKey') |
|
907 map_value = elem.get('mapValue') |
|
908 feature = model.ConfmlSequenceSetting(elem.get('ref'), mapKey=map_key, mapValue=map_value) |
|
909 elif typedef == 'int': |
|
910 feature = model.ConfmlIntSetting(elem.get('ref')) |
|
911 elif typedef == 'boolean': |
|
912 feature = model.ConfmlBooleanSetting(elem.get('ref')) |
|
913 elif typedef == 'selection': |
|
914 feature = model.ConfmlSelectionSetting(elem.get('ref')) |
|
915 elif typedef == 'multiSelection': |
|
916 feature = model.ConfmlMultiSelectionSetting(elem.get('ref')) |
|
917 elif typedef == 'string': |
|
918 feature = model.ConfmlStringSetting(elem.get('ref')) |
|
919 elif typedef == 'real': |
|
920 feature = model.ConfmlRealSetting(elem.get('ref')) |
|
921 elif typedef == 'file': |
|
922 feature = model.ConfmlFileSetting(elem.get('ref')) |
|
923 elif typedef == 'folder': |
|
924 feature = model.ConfmlFolderSetting(elem.get('ref')) |
|
925 elif typedef == 'date': |
|
926 feature = model.ConfmlDateSetting(elem.get('ref')) |
|
927 elif typedef == 'time': |
|
928 feature = model.ConfmlTimeSetting(elem.get('ref')) |
|
929 elif typedef == 'dateTime': |
|
930 feature = model.ConfmlDateTimeSetting(elem.get('ref')) |
|
931 elif typedef == 'duration': |
|
932 feature = model.ConfmlDurationSetting(elem.get('ref')) |
|
933 |
|
934 |
|
935 else: |
|
936 # Handle the default setting as int type |
|
937 feature = model.ConfmlSetting(elem.get('ref'), type=None) |
|
938 |
|
939 if elem.get('name'): |
|
940 feature.set_name(elem.get('name')) |
|
941 if elem.get('minOccurs'): |
|
942 feature.minOccurs = int(elem.get('minOccurs')) |
|
943 if elem.get('maxOccurs'): |
|
944 feature.maxOccurs = int(elem.get('maxOccurs')) |
|
945 if elem.get('readOnly'): |
|
946 feature.readOnly = elem.get('readOnly') == 'true' or False |
|
947 if elem.get('required'): |
|
948 feature.required = elem.get('required') == 'true' or False |
|
949 if elem.get('constraint'): |
|
950 feature.constraint = elem.get('constraint') |
|
951 if elem.get('relevant'): |
|
952 feature.relevant = elem.get('relevant') |
|
953 |
|
954 for elem in elem.getchildren(): |
|
955 # At the moment we ignore the namespace of elements |
|
956 (namespace,elemname) = get_elemname(elem.tag) |
|
957 try: |
|
958 reader = get_reader_for_elem(elemname) |
|
959 obj = reader.loads(elem) |
|
960 if obj != None: |
|
961 feature.add(obj,container.APPEND) |
|
962 else: |
|
963 logging.getLogger('cone').warning("Invalid child %s in %s" % (elem,feature.name)) |
|
964 except exceptions.ConePersistenceError,e: |
|
965 logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e)) |
|
966 continue |
|
967 return feature |
|
968 |
|
969 |
|
970 class ConfmlLocalPathWriter(ConfmlWriter): |
|
971 @classmethod |
|
972 def supported_class(cls, classname): |
|
973 """ |
|
974 Class method to determine if this ConfmlWriter supports writing |
|
975 of the given class name |
|
976 """ |
|
977 if classname=="ConfmlLocalPath": |
|
978 return True |
|
979 else: |
|
980 return False |
|
981 |
|
982 def dumps(self, obj): |
|
983 """ |
|
984 @param obj: The ConfmlLocalPath object |
|
985 """ |
|
986 elem = ElementTree.Element('localPath') |
|
987 if obj.readOnly: |
|
988 elem.set('readOnly', unicode(obj.readOnly)) |
|
989 return elem |
|
990 |
|
991 |
|
992 class ConfmlLocalPathReader(ConfmlReader): |
|
993 """ |
|
994 """ |
|
995 @classmethod |
|
996 def supported_elem(cls, elemname, parent=None): |
|
997 """ |
|
998 Class method to determine if this ConfmlWriter supports reading |
|
999 of the given elem name |
|
1000 """ |
|
1001 if elemname=="localPath": |
|
1002 return True |
|
1003 else: |
|
1004 return False |
|
1005 |
|
1006 def loads(self, elem): |
|
1007 """ |
|
1008 @param elem: The xml include elem |
|
1009 """ |
|
1010 return model.ConfmlLocalPath(readOnly=elem.get('readOnly')) |
|
1011 |
|
1012 |
|
1013 class ConfmlTargetPathWriter(ConfmlWriter): |
|
1014 @classmethod |
|
1015 def supported_class(cls, classname): |
|
1016 """ |
|
1017 Class method to determine if this ConfmlWriter supports writing |
|
1018 of the given class name |
|
1019 """ |
|
1020 if classname=="ConfmlTargetPath": |
|
1021 return True |
|
1022 else: |
|
1023 return False |
|
1024 |
|
1025 def dumps(self, obj): |
|
1026 """ |
|
1027 @param obj: The ConfmlLocalPath object |
|
1028 """ |
|
1029 elem = ElementTree.Element('targetPath') |
|
1030 if obj.readOnly: |
|
1031 elem.set('readOnly', unicode(obj.readOnly)) |
|
1032 return elem |
|
1033 |
|
1034 |
|
1035 class ConfmlTargetPathReader(ConfmlReader): |
|
1036 """ |
|
1037 """ |
|
1038 @classmethod |
|
1039 def supported_elem(cls, elemname, parent=None): |
|
1040 """ |
|
1041 Class method to determine if this ConfmlWriter supports reading |
|
1042 of the given elem name |
|
1043 """ |
|
1044 if elemname=="targetPath": |
|
1045 return True |
|
1046 else: |
|
1047 return False |
|
1048 |
|
1049 def loads(self, elem): |
|
1050 """ |
|
1051 @param elem: The xml include elem |
|
1052 """ |
|
1053 return model.ConfmlTargetPath(readOnly=elem.get('readOnly')) |
|
1054 |
|
1055 |
|
1056 class DummyWriter(ConfmlWriter): |
|
1057 """ |
|
1058 Dummy writer is executed on ConE model elements that are not supposed to go to the confml file |
|
1059 """ |
|
1060 @classmethod |
|
1061 def supported_class(cls, classname): |
|
1062 """ |
|
1063 Class method to determine if this ConfmlWriter supports writing |
|
1064 of the given class name |
|
1065 """ |
|
1066 if classname=="_FeatureProxy": |
|
1067 return True |
|
1068 else: |
|
1069 return False |
|
1070 |
|
1071 def dumps(self, obj): |
|
1072 return None |
|
1073 |
|
1074 |
|
1075 |
|
1076 class RfsReader(ConfmlReader): |
|
1077 """ |
|
1078 """ |
|
1079 @classmethod |
|
1080 def supported_elem(cls, elemname, parent=None): |
|
1081 """ |
|
1082 Class method to determine if this ConfmlWriter supports reading |
|
1083 of the given elem name |
|
1084 """ |
|
1085 if elemname=="rfs": |
|
1086 return True |
|
1087 else: |
|
1088 return False |
|
1089 |
|
1090 def loads(self, elem): |
|
1091 """ |
|
1092 @param elem: The xml include elem |
|
1093 """ |
|
1094 |
|
1095 (namespace,elemname) = get_elemname(elem.tag) |
|
1096 obj = api.DataContainer(elemname, container=True) |
|
1097 for elem in elem.getchildren(): |
|
1098 try: |
|
1099 reader = ElemReader(attr='rfs') |
|
1100 childobj = reader.loads(elem) |
|
1101 obj.add(childobj) |
|
1102 except exceptions.ConePersistenceError,e: |
|
1103 logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e)) |
|
1104 continue |
|
1105 return obj |
|
1106 |
|
1107 class ElemReader(ConfmlReader): |
|
1108 def __init__(self, **kwargs): |
|
1109 self.template = kwargs.get('template',False) |
|
1110 self.attr = kwargs.get('attr',None) |
|
1111 self.args = kwargs |
|
1112 |
|
1113 def loads(self, elem): |
|
1114 """ |
|
1115 @param elem: The xml include elem |
|
1116 """ |
|
1117 (namespace,elemname) = get_elemname(elem.tag) |
|
1118 datavalue = None |
|
1119 if len(list(elem)) == 0: |
|
1120 datavalue = elem.text |
|
1121 datatemplate = elem.get('template') == 'true' or self.template |
|
1122 dataextensionpolicy = elem.get('extensionPolicy') or '' |
|
1123 datamap = elem.get('map') |
|
1124 obj = api.Data(ref=elemname,value=datavalue, template=datatemplate, attr=self.attr,policy=dataextensionpolicy,map=datamap) |
|
1125 for elem in elem.getchildren(): |
|
1126 try: |
|
1127 reader = ElemReader(**self.args) |
|
1128 childobj = reader.loads(elem) |
|
1129 obj.add(childobj) |
|
1130 except exceptions.ConePersistenceError,e: |
|
1131 logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e)) |
|
1132 continue |
|
1133 return obj |
|
1134 |
|
1135 namespace_pattern = re.compile("{(.*)}(.*)") |
|
1136 nonamespace_pattern = re.compile("(.*)") |
|
1137 |
|
1138 def get_elemname(tag): |
|
1139 |
|
1140 ns = namespace_pattern.match(tag) |
|
1141 nn = nonamespace_pattern.match(tag) |
|
1142 if ns: |
|
1143 namespace = ns.group(1) |
|
1144 elemname = ns.group(2) |
|
1145 return (namespace,elemname) |
|
1146 elif nn: |
|
1147 namespace = "" |
|
1148 elemname = nn.group(1) |
|
1149 return (namespace,elemname) |
|
1150 else: |
|
1151 raise exceptions.ParseError("Could not parse tag %s" % tag) |
|
1152 |
|
1153 |
|
1154 def get_reader_for_elem(elemname, parent=None): |
|
1155 for reader in ConfmlReader.__subclasses__(): |
|
1156 if reader.supported_elem(elemname,parent): |
|
1157 return reader() |
|
1158 raise exceptions.ConePersistenceError("No reader for given elem %s under %s found!" % (elemname, parent)) |
|
1159 |
|
1160 def get_writer_for_class(classname): |
|
1161 for writer in ConfmlWriter.__subclasses__(): |
|
1162 if writer.supported_class(classname): |
|
1163 return writer () |
|
1164 raise exceptions.ConePersistenceError("No writer for given class found! %s" % classname) |