diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/confml/persistentconfml.py --- a/configurationengine/source/cone/confml/persistentconfml.py Wed Sep 08 12:20:56 2010 +0300 +++ b/configurationengine/source/cone/confml/persistentconfml.py Thu Oct 21 16:36:53 2010 +0300 @@ -16,6 +16,7 @@ import os import re import logging + try: from cElementTree import ElementTree except ImportError: @@ -35,7 +36,15 @@ INCLUDE_NAMESPACES = ["http://www.w3.org/2001/XInclude","http://www.w3.org/2001/xinclude"] XLINK_NAMESPACES = ["http://www.w3.org/1999/xlink"] SCHEMA_NAMESPACES = ["http://www.w3.org/2001/XMLSchema"] +RULEML_NAMESPACES = ["http://www.s60.com/xml/ruleml/3"] +RULEML_NAMESPACE = {"http://www.s60.com/xml/ruleml/3" : "ruleml"} CV_NAMESPACE = {"http://www.nokia.com/xml/cpf-id/1": "cv"} +KNOWN_NAMESPACES = [] +KNOWN_NAMESPACES.extend(CONFIGURATION_NAMESPACES) +KNOWN_NAMESPACES.extend(INCLUDE_NAMESPACES) +KNOWN_NAMESPACES.extend(XLINK_NAMESPACES) +KNOWN_NAMESPACES.extend(SCHEMA_NAMESPACES) +KNOWN_NAMESPACES.extend(CV_NAMESPACE) MODEL = model def dumps(obj, indent=True): @@ -365,6 +374,9 @@ elem.set('relevant', obj.get_relevant()) if obj.get_constraint() != None: elem.set('constraint', obj.get_constraint()) + + dump_extension_attributes(obj, elem) + for child in obj._objects(): """ Make sure that the object is mapped to an object in this model """ mobj = child._get_mapper('confml').map_object(child) @@ -408,14 +420,17 @@ feature.set_constraint(elem.get('constraint')) feature.set_type(type) feature.lineno = utils.etree.get_lineno(elem) + + load_extension_attributes(elem, feature) + for elem in elem.getchildren(): # At the moment we ignore the namespace of elements - (namespace,elemname) = get_elemname(elem.tag) + (_,elemname) = get_elemname(elem.tag) try: reader = get_reader_for_elem(elemname) obj = reader.loads(elem) feature.add(obj) - except exceptions.ConePersistenceError,e: + except exceptions.ConePersistenceError: add_unknown_element_warning(elem) continue return feature @@ -446,6 +461,13 @@ if obj.display_name is not None: objdict['displayName'] = obj.display_name if obj.map_value is not None: objdict['mapValue'] = obj.map_value + if hasattr(obj,'extensionAttributes') and obj.extensionAttributes is not None and obj.extensionAttributes != []: + for ext_attribute in obj.extensionAttributes: + if ext_attribute.ns != None and ext_attribute.ns != "": + objdict["{%s}%s" % (ext_attribute.ns, ext_attribute.name)] = str(ext_attribute.value) + else: + objdict[ext_attribute.name] = str(ext_attribute.value) + elem = ElementTree.Element('option', objdict) return elem @@ -482,6 +504,14 @@ map_value=elem.get('mapValue'), display_name=elem.get('displayName')) option.lineno = utils.etree.get_lineno(elem) + + #Add extension attributes + for attribute in elem.attrib: + (ns,attname) = get_elemname(attribute) + if ns != None and ns != "": + if not ns in KNOWN_NAMESPACES: + option.add_extension_attribute(model.ConfmlExtensionAttribute(attname, elem.attrib[attribute], ns)) + return option @@ -905,6 +935,13 @@ if hasattr(obj,'displayName') and obj.displayName is not None: elem.set('displayName', str(obj.displayName)) + if getattr(obj, 'extensionAttributes', None): + for ext_attribute in obj.extensionAttributes: + if ext_attribute.ns: + elem.set(("{%s}%s" % (ext_attribute.ns, ext_attribute.name)), str(ext_attribute.value)) + else: + elem.set(ext_attribute.name, str(ext_attribute.value)) + for child in obj._objects(): """ Make sure that the object is mapped to an object in this model """ mobj = child._get_mapper('confml').map_object(child) @@ -966,13 +1003,12 @@ feature = model.ConfmlDurationSetting(elem.get('ref')) elif typedef == 'hexBinary': feature = model.ConfmlHexBinarySetting(elem.get('ref')) - - else: # Handle the default setting as int type feature = model.ConfmlSetting(elem.get('ref'), type=typedef) feature.lineno = utils.etree.get_lineno(elem) self._get_setting_properties(elem, feature) + return feature def _get_setting_properties(self, elem, feature): @@ -996,12 +1032,20 @@ if elem.get('relevant'): feature.relevant = elem.get('relevant') + #Add extension attributes + for attribute in elem.attrib: + (ns,attname) = get_elemname(attribute) + if ns != None and ns != "": + if not ns in KNOWN_NAMESPACES: + feature.add_extension_attribute(model.ConfmlExtensionAttribute(attname, elem.attrib[attribute], ns)) + for elem in elem.getchildren(): # At the moment we ignore the namespace of elements (namespace,elemname) = get_elemname(elem.tag) try: reader = get_reader_for_elem(elemname) obj = reader.loads(elem) + if obj != None: feature.add(obj,container.APPEND) else: @@ -1171,7 +1215,155 @@ def dumps(self, obj): return None +class ExtensionsWriter(ConfmlWriter): + @classmethod + def supported_class(cls, classname): + """ + Class method to determine if this ConfmlWriter supports writing + of the given class name + """ + if classname=="ConfmlExtensions": + return True + else: + return False + def dumps(self, obj): + """ + @param obj: The Configuration object + """ + + elem = ElementTree.Element("extensions") + for extension in obj._objects(): + if isinstance(extension, api.RulemlEvalGlobals): + writer = EvalGlobalsWriter() + childelem = writer.dumps(extension) + if childelem != None: + elem.append(childelem) + else: + if extension.ns != None and extension.ns != "": + childelem = ElementTree.Element("{%s}%s" % (extension.ns, extension.tag)) + else: + childelem = ElementTree.Element(extension.tag) + if extension.value != None: + childelem.text = extension.value + for attr in extension.attrs: + childelem.set(attr, extension.attrs[attr]) + + childs = self._dump_childen(extension._objects()) + for ch in childs: + childelem.append(ch) + + elem.append(childelem) + return elem + + def _dump_childen(self, obj): + childs = [] + + for child in obj: + if child.ns != None and child.ns != "": + childelem = ElementTree.Element("{%s}%s" % (child.ns, child.tag)) + else: + childelem = ElementTree.Element(child.tag) + if child.value != None: + childelem.text = child.value + for attr in child.attrs: + childelem.set(attr, child.attrs[attr]) + + + chds = self._dump_childen(child._objects()) + for ch in chds: + childelem.append(ch) + + childs.append(childelem) + + return childs +#import xml.sax.expatreader + +class ExtensionsReader(ConfmlReader): + + @classmethod + def supported_elem(cls, elemname, parent=None): + """ + Class method to determine if this ConfmlWriter supports reading + of the given elem name + """ + if elemname=="extensions": + return True + else: + return False + + def loads(self,etree): + extensionselem = model.ConfmlExtensions() + extensionselem.lineno = utils.etree.get_lineno(etree) + for elem in etree.getchildren(): + try: + (_,elemname) = utils.xml.split_tag_namespace(elem.tag) + reader = get_reader_for_elem(elemname, 'extensions') + except exceptions.ConePersistenceError: + extensionselem._add(self._load_children(elem, etree), policy=container.APPEND) + else: + obj = reader.loads(elem) + if obj != None: + extensionselem._add(obj, policy=container.APPEND) + return extensionselem + + def _load_children(self, elem, etree): + (namespace,elemname) = get_elemname(elem.tag) + attributes = {} + for key in elem.keys(): + attributes[key] = elem.get(key) + + extension = model.ConfmlExtension(elemname, elem.text, namespace, attrs=attributes) + + for childelem in elem.getchildren(): + extension._add(self._load_children(childelem, etree), policy=container.APPEND) + + return extension + + +class EvalGlobalsWriter(ConfmlWriter): + @classmethod + def supported_class(cls, classname): + """ + Class method to determine if this ConfmlWriter supports writing + of the given class name + """ + if classname=="RulemlEvalGlobals": + return True + else: + return False + + def dumps(self, obj): + """ + @param obj: The Configuration object + """ + + elem = ElementTree.Element("{%s}eval_globals" % (RULEML_NAMESPACES[0])) + + if obj.value != None: + elem.text = obj.value + if obj.file != None: + elem.set('file', obj.file) + + return elem + +class EvalGlobalsReader(ConfmlReader): + + @classmethod + def supported_elem(cls, elemname, parent=None): + """ + Class method to determine if this ConfmlWriter supports reading + of the given elem name + """ + if elemname=="eval_globals": + return True + else: + return False + + def loads(self,etree): + eval_globals = api.RulemlEvalGlobals(etree.text, etree.get("file", None)) + + return eval_globals class RfsReader(ConfmlReader): """ @@ -1255,7 +1447,6 @@ return (namespace,elemname) else: raise exceptions.ParseError("Could not parse tag %s" % tag) - def get_reader_for_elem(elemname, parent=None): for reader in utils.all_subclasses(ConfmlReader): @@ -1268,3 +1459,18 @@ if writer.supported_class(classname): return writer () raise exceptions.ConePersistenceError("No writer for given class found! %s" % classname) + +def dump_extension_attributes(obj, elem): + if hasattr(obj,'extensionAttributes') and obj.extensionAttributes is not None and obj.extensionAttributes != []: + for ext_attribute in obj.extensionAttributes: + if ext_attribute.ns != None and ext_attribute.ns != "": + elem.set(("{%s}%s" % (ext_attribute.ns, ext_attribute.name)), unicode(ext_attribute.value)) + else: + elem.set(ext_attribute.name, unicode(ext_attribute.value)) + +def load_extension_attributes(elem, obj): + for attribute in elem.attrib: + (ns,attname) = get_elemname(attribute) + if ns != None and ns != "": + if not ns in KNOWN_NAMESPACES: + obj.add_extension_attribute(model.ConfmlExtensionAttribute(attname, elem.attrib[attribute], ns))