25 try: |
25 try: |
26 from xml.etree import cElementTree as ElementTree |
26 from xml.etree import cElementTree as ElementTree |
27 except ImportError: |
27 except ImportError: |
28 from xml.etree import ElementTree |
28 from xml.etree import ElementTree |
29 |
29 |
30 """ cone specific imports """ |
30 # cone specific imports |
31 from cone.public import persistence, exceptions, api, utils, container |
31 from cone.public import persistence, exceptions, api, utils, container, parsecontext |
32 from cone.confml import model |
32 from cone.confml import model |
33 |
33 |
34 CONFIGURATION_NAMESPACES = ["http://www.s60.com/xml/confml/2","http://www.s60.com/xml/confml/1"] |
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"] |
35 INCLUDE_NAMESPACES = ["http://www.w3.org/2001/XInclude","http://www.w3.org/2001/xinclude"] |
36 XLINK_NAMESPACES = ["http://www.w3.org/1999/xlink"] |
36 XLINK_NAMESPACES = ["http://www.w3.org/1999/xlink"] |
40 |
40 |
41 def dumps(obj, indent=True): |
41 def dumps(obj, indent=True): |
42 etree = ConfmlWriter().dumps(obj) |
42 etree = ConfmlWriter().dumps(obj) |
43 if indent: |
43 if indent: |
44 persistence.indent(etree) |
44 persistence.indent(etree) |
45 return ElementTree.tostring(etree) |
45 result = ElementTree.tostring(etree) |
|
46 |
|
47 # To make the output the same in linux and windows |
|
48 # (needed to make testing easier) |
|
49 if os.linesep != '\r\n': |
|
50 result = result.replace(os.linesep, '\r\n') |
|
51 |
|
52 return result |
46 |
53 |
47 def loads(xml): |
54 def loads(xml): |
48 return ConfmlReader().loads(xml) |
55 return ConfmlReader().loads(xml) |
49 |
56 |
50 |
57 def add_parse_warning(msg, line, type='model.confml'): |
|
58 parsecontext.get_confml_context().handle_problem( |
|
59 api.Problem(msg, |
|
60 severity = api.Problem.SEVERITY_WARNING, |
|
61 type = type, |
|
62 line = line)) |
|
63 |
|
64 def add_unknown_element_warning(elem): |
|
65 add_parse_warning("Unknown element '%s'" % elem.tag, |
|
66 utils.etree.get_lineno(elem), |
|
67 type='model.confml.unknown_element') |
51 |
68 |
52 class ConfmlWriter(persistence.ConeWriter): |
69 class ConfmlWriter(persistence.ConeWriter): |
53 """ |
70 """ |
54 """ |
71 """ |
55 def dumps(self, obj): |
72 def dumps(self, obj): |
67 def loads(self, xmlstr): |
84 def loads(self, xmlstr): |
68 """ |
85 """ |
69 @param xml: The xml which to read. reads only the first object. |
86 @param xml: The xml which to read. reads only the first object. |
70 """ |
87 """ |
71 reader = get_reader_for_elem("configuration") |
88 reader = get_reader_for_elem("configuration") |
72 etree = utils.etree.fromstring(xmlstr) |
89 try: |
|
90 etree = utils.etree.fromstring(xmlstr) |
|
91 except exceptions.XmlParseError, e: |
|
92 e.problem_type = 'xml.confml' |
|
93 raise e |
73 return reader.loads(etree) |
94 return reader.loads(etree) |
74 |
95 |
75 |
96 |
76 class ConfigurationWriter(ConfmlWriter): |
97 class ConfigurationWriter(ConfmlWriter): |
77 """ |
98 """ |
103 elem.set("xmlns:xi",self.include_namespace) |
124 elem.set("xmlns:xi",self.include_namespace) |
104 if self.include_namespace: |
125 if self.include_namespace: |
105 elem.set("xmlns:xlink",self.xlink_namespace) |
126 elem.set("xmlns:xlink",self.xlink_namespace) |
106 if self.schema_namespace: |
127 if self.schema_namespace: |
107 elem.set("xmlns:xs",self.schema_namespace) |
128 elem.set("xmlns:xs",self.schema_namespace) |
108 elem.set("name",obj.get_name()) |
129 if obj.get_name(): |
|
130 elem.set("name", obj.get_name()) |
|
131 if obj.version != None: |
|
132 elem.set("version", obj.version) |
|
133 if obj.get_id(): |
|
134 elem.set('id', obj.get_id()) |
|
135 |
109 for child in obj._objects(): |
136 for child in obj._objects(): |
110 """ Make sure that the object is mapped to an object in this model """ |
137 """ Make sure that the object is mapped to an object in this model """ |
111 mobj = child._get_mapper('confml').map_object(child) |
138 mobj = child._get_mapper('confml').map_object(child) |
112 writer = get_writer_for_class(mobj.__class__.__name__) |
139 writer = get_writer_for_class(mobj.__class__.__name__) |
113 childelem = writer.dumps(child) |
140 childelem = writer.dumps(child) |
135 self.configuration_namespaces = CONFIGURATION_NAMESPACES |
162 self.configuration_namespaces = CONFIGURATION_NAMESPACES |
136 self.include_namespaces = INCLUDE_NAMESPACES |
163 self.include_namespaces = INCLUDE_NAMESPACES |
137 self.schema_namespaces = SCHEMA_NAMESPACES |
164 self.schema_namespaces = SCHEMA_NAMESPACES |
138 |
165 |
139 def loads(self, etree): |
166 def loads(self, etree): |
140 configuration = model.ConfmlConfiguration("") |
167 configuration = model.ConfmlConfiguration(name=etree.get("name"), |
141 configuration.set_name(etree.get("name") or 'unknown') |
168 id=etree.get("id"), |
|
169 version=etree.get("version")) |
|
170 configuration.lineno = utils.etree.get_lineno(etree) |
|
171 # configuration.set_name(etree.get("name") or 'unknown') |
142 configuration.set_ref(etree.get("name") or 'unknown') |
172 configuration.set_ref(etree.get("name") or 'unknown') |
143 for elem in etree.getchildren(): |
173 for elem in etree.getchildren(): |
144 # At the moment we ignore the namespace of elements |
174 # At the moment we ignore the namespace of elements |
145 (namespace,elemname) = get_elemname(elem.tag) |
175 (namespace,elemname) = get_elemname(elem.tag) |
146 try: |
176 try: |
147 reader = get_reader_for_elem(elemname) |
177 reader = get_reader_for_elem(elemname) |
148 obj = reader.loads(elem) |
178 obj = reader.loads(elem) |
149 if obj: |
179 if obj: |
150 configuration.add(obj) |
180 configuration.add(obj) |
151 except exceptions.ConePersistenceError,e: |
181 except exceptions.ConePersistenceError,e: |
152 logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e)) |
182 add_unknown_element_warning(elem) |
153 continue |
183 continue |
154 return configuration |
184 return configuration |
155 |
185 |
156 |
186 |
157 class MetaWriter(ConfmlWriter): |
187 class MetaWriter(ConfmlWriter): |
200 else: |
230 else: |
201 return False |
231 return False |
202 |
232 |
203 def loads(self,etree): |
233 def loads(self,etree): |
204 metaelem = model.ConfmlMeta() |
234 metaelem = model.ConfmlMeta() |
|
235 metaelem.lineno = utils.etree.get_lineno(etree) |
205 for elem in etree.getchildren(): |
236 for elem in etree.getchildren(): |
206 (namespace,elemname) = get_elemname(elem.tag) |
237 (namespace,elemname) = get_elemname(elem.tag) |
207 attributes = {} |
238 attributes = {} |
208 for key in elem.keys(): |
239 for key in elem.keys(): |
209 attributes[key] = elem.get(key) |
240 attributes[key] = elem.get(key) |
293 |
325 |
294 def loads(self, elem): |
326 def loads(self, elem): |
295 """ |
327 """ |
296 @param elem: The xml include elem |
328 @param elem: The xml include elem |
297 """ |
329 """ |
298 |
330 proxy = api.ConfigurationProxy(self.parse_include(elem)) |
299 return api.ConfigurationProxy(self.parse_include(elem)) |
331 # proxy.lineno = utils.etree.get_lineno(elem) |
|
332 return proxy |
300 |
333 |
301 def parse_include(self,include): |
334 def parse_include(self,include): |
302 #print "Found include %s" % include.get('href').replace('#/','') |
335 #print "Found include %s" % include.get('href').replace('#/','') |
303 return include.get('href').replace('#/','') |
336 return include.get('href').replace('#/','') |
304 |
337 |
319 def dumps(self, obj): |
352 def dumps(self, obj): |
320 """ |
353 """ |
321 @param obj: The Configuration object |
354 @param obj: The Configuration object |
322 """ |
355 """ |
323 elem = ElementTree.Element('feature', |
356 elem = ElementTree.Element('feature', |
324 {'ref' : obj.get_ref(), |
357 {'ref' : obj.get_ref()}) |
325 'name' : obj.get_name()}) |
358 if obj.get_name(): |
|
359 elem.set('name', obj.get_name()) |
326 if obj.get_type(): |
360 if obj.get_type(): |
327 elem.set('type', obj.get_type()) |
361 elem.set('type', obj.get_type()) |
|
362 if obj.get_id() != None: |
|
363 elem.set('id', obj.get_id()) |
|
364 if obj.get_relevant() != None: |
|
365 elem.set('relevant', obj.get_relevant()) |
|
366 if obj.get_constraint() != None: |
|
367 elem.set('constraint', obj.get_constraint()) |
328 for child in obj._objects(): |
368 for child in obj._objects(): |
329 """ Make sure that the object is mapped to an object in this model """ |
369 """ Make sure that the object is mapped to an object in this model """ |
330 mobj = child._get_mapper('confml').map_object(child) |
370 mobj = child._get_mapper('confml').map_object(child) |
331 writer = get_writer_for_class(mobj.__class__.__name__) |
371 writer = get_writer_for_class(mobj.__class__.__name__) |
332 childelem = writer.dumps(child) |
372 childelem = writer.dumps(child) |
358 feature = api.FeatureSequence(elem.get('ref')) |
398 feature = api.FeatureSequence(elem.get('ref')) |
359 else: |
399 else: |
360 feature = model.ConfmlFeature(elem.get('ref')) |
400 feature = model.ConfmlFeature(elem.get('ref')) |
361 if elem.get('name'): |
401 if elem.get('name'): |
362 feature.set_name(elem.get('name')) |
402 feature.set_name(elem.get('name')) |
|
403 if elem.get('id') != None: |
|
404 feature.set_id(elem.get('id')) |
|
405 if elem.get('relevant') != None: |
|
406 feature.set_relevant(elem.get('relevant')) |
|
407 if elem.get('constraint') != None: |
|
408 feature.set_constraint(elem.get('constraint')) |
363 feature.set_type(type) |
409 feature.set_type(type) |
|
410 feature.lineno = utils.etree.get_lineno(elem) |
364 for elem in elem.getchildren(): |
411 for elem in elem.getchildren(): |
365 # At the moment we ignore the namespace of elements |
412 # At the moment we ignore the namespace of elements |
366 (namespace,elemname) = get_elemname(elem.tag) |
413 (namespace,elemname) = get_elemname(elem.tag) |
367 try: |
414 try: |
368 reader = get_reader_for_elem(elemname) |
415 reader = get_reader_for_elem(elemname) |
369 obj = reader.loads(elem) |
416 obj = reader.loads(elem) |
370 feature.add(obj) |
417 feature.add(obj) |
371 except exceptions.ConePersistenceError,e: |
418 except exceptions.ConePersistenceError,e: |
372 logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e)) |
419 add_unknown_element_warning(elem) |
373 continue |
420 continue |
374 return feature |
421 return feature |
375 |
422 |
376 |
423 |
377 class OptionWriter(ConfmlWriter): |
424 class OptionWriter(ConfmlWriter): |
394 objdict = {} |
441 objdict = {} |
395 if obj.get_name() is not None: objdict['name'] = obj.get_name() |
442 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() |
443 if obj.get_value() is not None: objdict['value'] = obj.get_value() |
397 if obj.map is not None: objdict['map'] = obj.map |
444 if obj.map is not None: objdict['map'] = obj.map |
398 if obj.relevant is not None: objdict['relevant'] = obj.relevant |
445 if obj.relevant is not None: objdict['relevant'] = obj.relevant |
|
446 if obj.display_name is not None: objdict['displayName'] = obj.display_name |
|
447 if obj.map_value is not None: objdict['mapValue'] = obj.map_value |
|
448 |
399 elem = ElementTree.Element('option', objdict) |
449 elem = ElementTree.Element('option', objdict) |
400 |
450 |
401 return elem |
451 return elem |
402 |
452 |
403 |
453 |
420 @param elem: The xml include elem |
470 @param elem: The xml include elem |
421 """ |
471 """ |
422 name = elem.get('name') |
472 name = elem.get('name') |
423 value = elem.get('value') |
473 value = elem.get('value') |
424 optmap = elem.get('map') |
474 optmap = elem.get('map') |
|
475 |
425 if value == None and optmap == None: |
476 if value == None and optmap == None: |
426 logging.getLogger('cone').warning("Encountered option with no value") |
477 logging.getLogger('cone').warning("Encountered option with no value") |
427 option = None |
478 option = None |
428 else: |
479 else: |
429 option = api.Option(name, value, map=optmap, relevant=elem.get('relevant')) |
480 option = api.Option(name, value, map=optmap, |
|
481 relevant=elem.get('relevant'), |
|
482 map_value=elem.get('mapValue'), |
|
483 display_name=elem.get('displayName')) |
|
484 option.lineno = utils.etree.get_lineno(elem) |
430 return option |
485 return option |
431 |
486 |
432 |
487 |
433 class IconWriter(ConfmlWriter): |
488 class IconWriter(ConfmlWriter): |
434 @classmethod |
489 @classmethod |
469 """ |
524 """ |
470 @param elem: The xml include elem |
525 @param elem: The xml include elem |
471 """ |
526 """ |
472 href = elem.get('{%s}href' % XLINK_NAMESPACES[0]) |
527 href = elem.get('{%s}href' % XLINK_NAMESPACES[0]) |
473 obj = model.ConfmlIcon(href) |
528 obj = model.ConfmlIcon(href) |
|
529 obj.lineno = utils.etree.get_lineno(elem) |
474 return obj |
530 return obj |
475 |
531 |
476 |
532 |
477 class PropertyWriter(ConfmlWriter): |
533 class PropertyWriter(ConfmlWriter): |
478 @classmethod |
534 @classmethod |
479 def supported_class(cls, classname): |
535 def supported_class(cls, classname): |
480 """ |
536 """ |
481 Class method to determine if this ConfmlWriter supports writing |
537 Class method to determine if this ConfmlWriter supports writing |
482 of the given class name |
538 of the given class name |
483 """ |
539 """ |
484 if classname=="ConfmlProperty": |
540 if classname=="Property": |
485 return True |
541 return True |
486 else: |
542 else: |
487 return False |
543 return False |
488 |
544 |
489 def dumps(self, obj): |
545 def dumps(self, obj): |
516 |
572 |
517 def loads(self, elem): |
573 def loads(self, elem): |
518 """ |
574 """ |
519 @param elem: The xml include elem |
575 @param elem: The xml include elem |
520 """ |
576 """ |
521 option = model.ConfmlProperty(name=elem.get('name'),value=elem.get('value'), unit=elem.get('unit')) |
577 option = api.Property(name=elem.get('name'),value=elem.get('value'), unit=elem.get('unit')) |
|
578 option.lineno = utils.etree.get_lineno(elem) |
522 return option |
579 return option |
523 |
580 |
524 |
581 |
525 class XmlSchemaFacetWriter(ConfmlWriter): |
582 class XmlSchemaFacetWriter(ConfmlWriter): |
526 MAPPING = {'ConfmlLength' : 'xs:length', |
583 MAPPING = {'ConfmlLength' : 'xs:length', |
572 @param elem: The XML schema facet element |
629 @param elem: The XML schema facet element |
573 """ |
630 """ |
574 elem_name = utils.xml.split_tag_namespace(elem.tag)[1] |
631 elem_name = utils.xml.split_tag_namespace(elem.tag)[1] |
575 facet_class = self.MAPPING[elem_name] |
632 facet_class = self.MAPPING[elem_name] |
576 obj = facet_class(elem.get('value')) |
633 obj = facet_class(elem.get('value')) |
|
634 obj.lineno = utils.etree.get_lineno(elem) |
577 return obj |
635 return obj |
578 |
636 |
579 |
637 |
580 class DataWriter(ConfmlWriter): |
638 class DataWriter(ConfmlWriter): |
581 @classmethod |
639 @classmethod |
582 def supported_class(cls, classname): |
640 def supported_class(cls, classname): |
583 """ |
641 """ |
584 Class method to determine if this ConfmlWriter supports writing |
642 Class method to determine if this ConfmlWriter supports writing |
585 of the given class name |
643 of the given class name |
586 """ |
644 """ |
587 if classname=="Data": |
645 if classname=="Data" or \ |
588 return True |
646 classname=="DataContainer": |
589 if classname=="DataContainer": |
|
590 return True |
647 return True |
591 else: |
648 else: |
592 return False |
649 return False |
593 |
650 |
594 def dumps(self, obj): |
651 def dumps(self, obj): |
595 """ |
652 """ |
596 @param obj: The Data object |
653 @param obj: The Data object |
597 """ |
654 """ |
598 # Create a data hierarchy of the |
655 # Create a data hierarchy of the |
599 elem = ElementTree.Element(obj.get_ref()) |
656 elem = ElementTree.Element(obj.get_ref()) |
600 if hasattr(obj,'get_value') and obj.get_value() and not obj.get_map(): |
657 if hasattr(obj,'get_map') and obj.get_map() is not None: |
|
658 elem.set('map', obj.get_map()) |
|
659 elif hasattr(obj,'get_value') and obj.get_value() is not None: |
601 elem.text = obj.get_value() |
660 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: |
661 if hasattr(obj,'template') and obj.template == True: |
605 elem.set('template','true') |
662 elem.set('template','true') |
606 if hasattr(obj,'policy') and obj.policy != '': |
663 if hasattr(obj,'policy') and obj.policy != '': |
607 elem.set('extensionPolicy',obj.policy) |
664 elem.set('extensionPolicy',obj.policy) |
|
665 if hasattr(obj,'empty') and obj.empty == True: |
|
666 elem.set('empty','true') |
608 for child in obj._objects(): |
667 for child in obj._objects(): |
609 writer = DataWriter() |
668 writer = DataWriter() |
610 childelem = writer.dumps(child) |
669 childelem = writer.dumps(child) |
611 if childelem != None: |
670 if childelem != None: |
612 elem.append(childelem) |
671 elem.append(childelem) |
632 @param elem: The xml include elem |
691 @param elem: The xml include elem |
633 """ |
692 """ |
634 |
693 |
635 (namespace,elemname) = get_elemname(elem.tag) |
694 (namespace,elemname) = get_elemname(elem.tag) |
636 obj = api.DataContainer(elemname, container=True) |
695 obj = api.DataContainer(elemname, container=True) |
|
696 obj.lineno = utils.etree.get_lineno(elem) |
637 for elem in elem.getchildren(): |
697 for elem in elem.getchildren(): |
638 try: |
698 try: |
639 reader = ElemReader(attr='data') |
699 reader = ElemReader(attr='data') |
640 childobj = reader.loads(elem) |
700 childobj = reader.loads(elem) |
641 obj.add(childobj) |
701 obj.add(childobj) |
642 except exceptions.ConePersistenceError,e: |
702 except exceptions.ConePersistenceError,e: |
643 logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e)) |
703 add_unknown_element_warning(elem) |
644 continue |
704 continue |
645 return obj |
705 return obj |
646 |
706 |
647 |
707 |
648 class ViewWriter(ConfmlWriter): |
708 class ViewWriter(ConfmlWriter): |
661 def dumps(self, obj): |
721 def dumps(self, obj): |
662 """ |
722 """ |
663 @param obj: The Configuration object |
723 @param obj: The Configuration object |
664 """ |
724 """ |
665 elem = ElementTree.Element('view', |
725 elem = ElementTree.Element('view', |
666 {'id' : obj.get_ref(), |
726 {'name' : obj.get_name()}) |
667 'name' : obj.get_name()}) |
727 if obj.id != None: |
|
728 elem.set('id', obj.id) |
668 for child in obj._objects(): |
729 for child in obj._objects(): |
669 """ Make sure that the object is mapped to an object in this model """ |
730 """ Make sure that the object is mapped to an object in this model """ |
670 mobj = child._get_mapper('confml').map_object(child) |
731 mobj = child._get_mapper('confml').map_object(child) |
671 writer = get_writer_for_class(mobj.__class__.__name__) |
732 writer = get_writer_for_class(mobj.__class__.__name__) |
672 childelem = writer.dumps(child) |
733 childelem = writer.dumps(child) |
694 @param elem: The xml include elem |
755 @param elem: The xml include elem |
695 """ |
756 """ |
696 vid = elem.get('id') |
757 vid = elem.get('id') |
697 name = elem.get('name') |
758 name = elem.get('name') |
698 view = model.ConfmlView(name, id=vid) |
759 view = model.ConfmlView(name, id=vid) |
|
760 view.lineno = utils.etree.get_lineno(elem) |
699 for elem in elem.getchildren(): |
761 for elem in elem.getchildren(): |
700 # At the moment we ignore the namespace of elements |
762 # At the moment we ignore the namespace of elements |
701 (namespace,elemname) = get_elemname(elem.tag) |
763 (namespace,elemname) = get_elemname(elem.tag) |
702 try: |
764 try: |
703 reader = get_reader_for_elem(elemname) |
765 reader = get_reader_for_elem(elemname) |
704 obj = reader.loads(elem) |
766 obj = reader.loads(elem) |
705 view.add(obj) |
767 view.add(obj) |
706 except exceptions.ConePersistenceError,e: |
768 except exceptions.ConePersistenceError,e: |
707 logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e)) |
769 add_unknown_element_warning(elem) |
708 continue |
770 continue |
709 return view |
771 return view |
710 |
772 |
711 |
773 |
712 class GroupWriter(ConfmlWriter): |
774 class GroupWriter(ConfmlWriter): |
725 """ |
787 """ |
726 @param obj: The Configuration object |
788 @param obj: The Configuration object |
727 """ |
789 """ |
728 elem = ElementTree.Element('group', |
790 elem = ElementTree.Element('group', |
729 {'name' : obj.get_name()}) |
791 {'name' : obj.get_name()}) |
|
792 if obj.get_id(): |
|
793 elem.set('id', obj.get_id()) |
|
794 |
730 for child in obj._objects(): |
795 for child in obj._objects(): |
731 """ Make sure that the object is mapped to an object in this model """ |
796 """ Make sure that the object is mapped to an object in this model """ |
732 mobj = child._get_mapper('confml').map_object(child) |
797 mobj = child._get_mapper('confml').map_object(child) |
733 writer = get_writer_for_class(mobj.__class__.__name__) |
798 writer = get_writer_for_class(mobj.__class__.__name__) |
734 childelem = writer.dumps(child) |
799 childelem = writer.dumps(child) |
756 @param elem: The xml include elem |
821 @param elem: The xml include elem |
757 """ |
822 """ |
758 gname = elem.get('name') |
823 gname = elem.get('name') |
759 gref = utils.resourceref.to_dref(gname).replace('.','_') |
824 gref = utils.resourceref.to_dref(gname).replace('.','_') |
760 group = model.ConfmlGroup(gref, name=gname) |
825 group = model.ConfmlGroup(gref, name=gname) |
|
826 group.lineno = utils.etree.get_lineno(elem) |
|
827 if elem.get('id'): |
|
828 group.set_id(elem.get('id')) |
761 for elem in elem.getchildren(): |
829 for elem in elem.getchildren(): |
762 # At the moment we ignore the namespace of elements |
830 # At the moment we ignore the namespace of elements |
763 (namespace,elemname) = get_elemname(elem.tag) |
831 (namespace,elemname) = get_elemname(elem.tag) |
764 try: |
832 try: |
765 reader = get_reader_for_elem(elemname, 'group') |
833 reader = get_reader_for_elem(elemname, 'group') |
766 obj = reader.loads(elem) |
834 obj = reader.loads(elem) |
767 if obj != None: |
835 if obj != None: |
768 group.add(obj) |
836 group.add(obj) |
769 except exceptions.ConePersistenceError,e: |
837 except exceptions.ConePersistenceError,e: |
770 logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e)) |
838 add_unknown_element_warning(elem) |
771 continue |
839 continue |
772 return group |
840 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 |
841 |
821 |
842 |
822 class ConfmlSettingWriter(ConfmlWriter): |
843 class ConfmlSettingWriter(ConfmlWriter): |
823 @classmethod |
844 @classmethod |
824 def supported_class(cls, classname): |
845 def supported_class(cls, classname): |
835 classname=="ConfmlMultiSelectionSetting" or \ |
856 classname=="ConfmlMultiSelectionSetting" or \ |
836 classname=="ConfmlDateSetting" or \ |
857 classname=="ConfmlDateSetting" or \ |
837 classname=="ConfmlTimeSetting" or \ |
858 classname=="ConfmlTimeSetting" or \ |
838 classname=="ConfmlDateTimeSetting" or \ |
859 classname=="ConfmlDateTimeSetting" or \ |
839 classname=="ConfmlDurationSetting" or \ |
860 classname=="ConfmlDurationSetting" or \ |
|
861 classname=="ConfmlHexBinarySetting" or \ |
840 classname=="ConfmlFileSetting" or \ |
862 classname=="ConfmlFileSetting" or \ |
841 classname=="ConfmlFolderSetting" or \ |
863 classname=="ConfmlFolderSetting" or \ |
842 classname=="FeatureSequence" or \ |
864 classname=="FeatureSequence" or \ |
843 classname=="ConfmlSequenceSetting": |
865 classname=="ConfmlSequenceSetting": |
844 return True |
866 return True |
848 def dumps(self, obj): |
870 def dumps(self, obj): |
849 """ |
871 """ |
850 @param obj: The Configuration object |
872 @param obj: The Configuration object |
851 """ |
873 """ |
852 elem = ElementTree.Element('setting', |
874 elem = ElementTree.Element('setting', |
853 {'ref' : obj.get_ref(), |
875 {'ref' : obj.get_ref()}) |
854 'name' : obj.get_name()}) |
876 self._set_setting_properties(elem, obj) |
|
877 return elem |
|
878 |
|
879 def _set_setting_properties(self, elem, obj): |
|
880 """ |
|
881 Set the setting properties for the given elm from the given feature object |
|
882 """ |
|
883 if obj.get_name(): |
|
884 elem.set('name', obj.get_name()) |
855 if obj.type: |
885 if obj.type: |
856 elem.set('type', obj.get_type()) |
886 elem.set('type', obj.get_type()) |
|
887 if obj.get_id(): |
|
888 elem.set('id', obj.get_id()) |
857 if hasattr(obj,'minOccurs'): |
889 if hasattr(obj,'minOccurs'): |
858 elem.set('minOccurs', str(obj.minOccurs)) |
890 elem.set('minOccurs', str(obj.minOccurs)) |
859 if hasattr(obj,'maxOccurs'): |
891 if hasattr(obj,'maxOccurs'): |
860 elem.set('maxOccurs', str(obj.maxOccurs)) |
892 elem.set('maxOccurs', str(obj.maxOccurs)) |
861 if hasattr(obj,'readOnly') and obj.readOnly != None: |
893 if hasattr(obj,'readOnly') and obj.readOnly != None: |
868 elem.set('relevant', obj.relevant) |
900 elem.set('relevant', obj.relevant) |
869 if hasattr(obj,'mapKey') and obj.mapKey is not None: |
901 if hasattr(obj,'mapKey') and obj.mapKey is not None: |
870 elem.set('mapKey', str(obj.mapKey)) |
902 elem.set('mapKey', str(obj.mapKey)) |
871 if hasattr(obj,'mapValue') and obj.mapValue is not None: |
903 if hasattr(obj,'mapValue') and obj.mapValue is not None: |
872 elem.set('mapValue', str(obj.mapValue)) |
904 elem.set('mapValue', str(obj.mapValue)) |
|
905 if hasattr(obj,'displayName') and obj.displayName is not None: |
|
906 elem.set('displayName', str(obj.displayName)) |
873 |
907 |
874 for child in obj._objects(): |
908 for child in obj._objects(): |
875 """ Make sure that the object is mapped to an object in this model """ |
909 """ Make sure that the object is mapped to an object in this model """ |
876 mobj = child._get_mapper('confml').map_object(child) |
910 mobj = child._get_mapper('confml').map_object(child) |
877 writer = get_writer_for_class(mobj.__class__.__name__) |
911 writer = get_writer_for_class(mobj.__class__.__name__) |
878 childelem = writer.dumps(child) |
912 childelem = writer.dumps(child) |
879 if childelem != None: |
913 if childelem != None: |
880 elem.append(childelem) |
914 elem.append(childelem) |
881 return elem |
|
882 |
915 |
883 |
916 |
884 class ConfmlSettingReader(ConfmlReader): |
917 class ConfmlSettingReader(ConfmlReader): |
885 """ |
918 """ |
886 """ |
919 """ |
903 """ |
936 """ |
904 typedef = elem.get('type') |
937 typedef = elem.get('type') |
905 if typedef == 'sequence': |
938 if typedef == 'sequence': |
906 map_key = elem.get('mapKey') |
939 map_key = elem.get('mapKey') |
907 map_value = elem.get('mapValue') |
940 map_value = elem.get('mapValue') |
908 feature = model.ConfmlSequenceSetting(elem.get('ref'), mapKey=map_key, mapValue=map_value) |
941 display_name = elem.get('displayName') |
|
942 feature = model.ConfmlSequenceSetting(elem.get('ref'), mapKey=map_key, mapValue=map_value, displayName=display_name) |
909 elif typedef == 'int': |
943 elif typedef == 'int': |
910 feature = model.ConfmlIntSetting(elem.get('ref')) |
944 feature = model.ConfmlIntSetting(elem.get('ref')) |
911 elif typedef == 'boolean': |
945 elif typedef == 'boolean': |
912 feature = model.ConfmlBooleanSetting(elem.get('ref')) |
946 feature = model.ConfmlBooleanSetting(elem.get('ref')) |
913 elif typedef == 'selection': |
947 elif typedef == 'selection': |
928 feature = model.ConfmlTimeSetting(elem.get('ref')) |
962 feature = model.ConfmlTimeSetting(elem.get('ref')) |
929 elif typedef == 'dateTime': |
963 elif typedef == 'dateTime': |
930 feature = model.ConfmlDateTimeSetting(elem.get('ref')) |
964 feature = model.ConfmlDateTimeSetting(elem.get('ref')) |
931 elif typedef == 'duration': |
965 elif typedef == 'duration': |
932 feature = model.ConfmlDurationSetting(elem.get('ref')) |
966 feature = model.ConfmlDurationSetting(elem.get('ref')) |
|
967 elif typedef == 'hexBinary': |
|
968 feature = model.ConfmlHexBinarySetting(elem.get('ref')) |
933 |
969 |
934 |
970 |
935 else: |
971 else: |
936 # Handle the default setting as int type |
972 # Handle the default setting as int type |
937 feature = model.ConfmlSetting(elem.get('ref'), type=None) |
973 feature = model.ConfmlSetting(elem.get('ref'), type=typedef) |
|
974 feature.lineno = utils.etree.get_lineno(elem) |
|
975 self._get_setting_properties(elem, feature) |
|
976 return feature |
938 |
977 |
|
978 def _get_setting_properties(self, elem, feature): |
|
979 """ |
|
980 Get the setting properties for the given feature from the given xml elem |
|
981 """ |
939 if elem.get('name'): |
982 if elem.get('name'): |
940 feature.set_name(elem.get('name')) |
983 feature.set_name(elem.get('name')) |
|
984 if elem.get('id'): |
|
985 feature.set_id(elem.get('id')) |
941 if elem.get('minOccurs'): |
986 if elem.get('minOccurs'): |
942 feature.minOccurs = int(elem.get('minOccurs')) |
987 feature.minOccurs = int(elem.get('minOccurs')) |
943 if elem.get('maxOccurs'): |
988 if elem.get('maxOccurs'): |
944 feature.maxOccurs = int(elem.get('maxOccurs')) |
989 feature.maxOccurs = int(elem.get('maxOccurs')) |
945 if elem.get('readOnly'): |
990 if elem.get('readOnly'): |
958 reader = get_reader_for_elem(elemname) |
1003 reader = get_reader_for_elem(elemname) |
959 obj = reader.loads(elem) |
1004 obj = reader.loads(elem) |
960 if obj != None: |
1005 if obj != None: |
961 feature.add(obj,container.APPEND) |
1006 feature.add(obj,container.APPEND) |
962 else: |
1007 else: |
963 logging.getLogger('cone').warning("Invalid child %s in %s" % (elem,feature.name)) |
1008 add_parse_warning("Invalid child %s in %s" % (elem, feature.name), |
|
1009 utils.etree.get_lineno(elem)) |
964 except exceptions.ConePersistenceError,e: |
1010 except exceptions.ConePersistenceError,e: |
965 logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e)) |
1011 add_unknown_element_warning(elem) |
966 continue |
1012 continue |
967 return feature |
1013 |
968 |
1014 |
|
1015 class GroupSettingWriter(ConfmlSettingWriter): |
|
1016 """ |
|
1017 """ |
|
1018 @classmethod |
|
1019 def supported_class(cls, classname): |
|
1020 """ |
|
1021 Class method to determine if this ConfmlWriter supports writing |
|
1022 of the given class name |
|
1023 """ |
|
1024 if classname=="FeatureLink" or \ |
|
1025 classname=="ConfmlFeatureLink": |
|
1026 return True |
|
1027 else: |
|
1028 return False |
|
1029 |
|
1030 def dumps(self, obj): |
|
1031 """ |
|
1032 @param obj: The Configuration object |
|
1033 """ |
|
1034 ref = obj.fqr.replace('.','/') |
|
1035 elem = ElementTree.Element('setting', |
|
1036 {'ref' : ref}) |
|
1037 self._set_setting_properties(elem, obj) |
|
1038 return elem |
|
1039 |
|
1040 |
|
1041 class GroupSettingReader(ConfmlSettingReader): |
|
1042 """ |
|
1043 """ |
|
1044 @classmethod |
|
1045 def supported_elem(cls, elemname, parent=None): |
|
1046 """ |
|
1047 Class method to determine if this ConfmlWriter supports reading |
|
1048 of the given elem name |
|
1049 """ |
|
1050 if elemname=='setting' and parent=='group': |
|
1051 return True |
|
1052 else: |
|
1053 return False |
|
1054 |
|
1055 def loads(self, elem): |
|
1056 """ |
|
1057 @param elem: The xml include elem |
|
1058 """ |
|
1059 ref = elem.get('ref') or '' |
|
1060 ref = ref.replace('/','.') |
|
1061 feature_link = model.ConfmlFeatureLink(ref) |
|
1062 feature_link.lineno = utils.etree.get_lineno(elem) |
|
1063 self._get_setting_properties(elem, feature_link) |
|
1064 return feature_link |
969 |
1065 |
970 class ConfmlLocalPathWriter(ConfmlWriter): |
1066 class ConfmlLocalPathWriter(ConfmlWriter): |
971 @classmethod |
1067 @classmethod |
972 def supported_class(cls, classname): |
1068 def supported_class(cls, classname): |
973 """ |
1069 """ |
1092 @param elem: The xml include elem |
1192 @param elem: The xml include elem |
1093 """ |
1193 """ |
1094 |
1194 |
1095 (namespace,elemname) = get_elemname(elem.tag) |
1195 (namespace,elemname) = get_elemname(elem.tag) |
1096 obj = api.DataContainer(elemname, container=True) |
1196 obj = api.DataContainer(elemname, container=True) |
|
1197 obj.lineno = utils.etree.get_lineno(elem) |
1097 for elem in elem.getchildren(): |
1198 for elem in elem.getchildren(): |
1098 try: |
1199 try: |
1099 reader = ElemReader(attr='rfs') |
1200 reader = ElemReader(attr='rfs') |
1100 childobj = reader.loads(elem) |
1201 childobj = reader.loads(elem) |
1101 obj.add(childobj) |
1202 obj.add(childobj) |
1102 except exceptions.ConePersistenceError,e: |
1203 except exceptions.ConePersistenceError,e: |
1103 logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e)) |
1204 add_unknown_element_warning(elem) |
1104 continue |
1205 continue |
1105 return obj |
1206 return obj |
1106 |
1207 |
1107 class ElemReader(ConfmlReader): |
1208 class ElemReader(ConfmlReader): |
1108 def __init__(self, **kwargs): |
1209 def __init__(self, **kwargs): |
1116 """ |
1217 """ |
1117 (namespace,elemname) = get_elemname(elem.tag) |
1218 (namespace,elemname) = get_elemname(elem.tag) |
1118 datavalue = None |
1219 datavalue = None |
1119 if len(list(elem)) == 0: |
1220 if len(list(elem)) == 0: |
1120 datavalue = elem.text |
1221 datavalue = elem.text |
1121 datatemplate = elem.get('template') == 'true' or self.template |
1222 obj = model.ConfmlData( |
1122 dataextensionpolicy = elem.get('extensionPolicy') or '' |
1223 ref = elemname, |
1123 datamap = elem.get('map') |
1224 value = datavalue, |
1124 obj = api.Data(ref=elemname,value=datavalue, template=datatemplate, attr=self.attr,policy=dataextensionpolicy,map=datamap) |
1225 template = elem.get('template') == 'true' or self.template, |
|
1226 attr = self.attr, |
|
1227 policy = elem.get('extensionPolicy') or '', |
|
1228 map = elem.get('map'), |
|
1229 empty = elem.get('empty') == 'true') |
|
1230 obj.lineno = utils.etree.get_lineno(elem) |
1125 for elem in elem.getchildren(): |
1231 for elem in elem.getchildren(): |
1126 try: |
1232 try: |
1127 reader = ElemReader(**self.args) |
1233 reader = ElemReader(**self.args) |
1128 childobj = reader.loads(elem) |
1234 childobj = reader.loads(elem) |
1129 obj.add(childobj) |
1235 obj.add(childobj) |
1150 else: |
1256 else: |
1151 raise exceptions.ParseError("Could not parse tag %s" % tag) |
1257 raise exceptions.ParseError("Could not parse tag %s" % tag) |
1152 |
1258 |
1153 |
1259 |
1154 def get_reader_for_elem(elemname, parent=None): |
1260 def get_reader_for_elem(elemname, parent=None): |
1155 for reader in ConfmlReader.__subclasses__(): |
1261 for reader in utils.all_subclasses(ConfmlReader): |
1156 if reader.supported_elem(elemname,parent): |
1262 if reader.supported_elem(elemname,parent): |
1157 return reader() |
1263 return reader() |
1158 raise exceptions.ConePersistenceError("No reader for given elem %s under %s found!" % (elemname, parent)) |
1264 raise exceptions.ConePersistenceError("No reader for given elem %s under %s found!" % (elemname, parent)) |
1159 |
1265 |
1160 def get_writer_for_class(classname): |
1266 def get_writer_for_class(classname): |
1161 for writer in ConfmlWriter.__subclasses__(): |
1267 for writer in utils.all_subclasses(ConfmlWriter): |
1162 if writer.supported_class(classname): |
1268 if writer.supported_class(classname): |
1163 return writer () |
1269 return writer () |
1164 raise exceptions.ConePersistenceError("No writer for given class found! %s" % classname) |
1270 raise exceptions.ConePersistenceError("No writer for given class found! %s" % classname) |