configurationengine/source/cone/confml/persistentconfml.py
changeset 5 d2c80f5cab53
parent 3 e7e0ae78773e
equal deleted inserted replaced
4:0951727b8815 5:d2c80f5cab53
    14 # Description: 
    14 # Description: 
    15 #
    15 #
    16 import os
    16 import os
    17 import re
    17 import re
    18 import logging
    18 import logging
       
    19 
    19 try:
    20 try:
    20     from cElementTree import ElementTree
    21     from cElementTree import ElementTree
    21 except ImportError:
    22 except ImportError:
    22     try:    
    23     try:    
    23         from elementtree import ElementTree
    24         from elementtree import ElementTree
    33 
    34 
    34 CONFIGURATION_NAMESPACES = ["http://www.s60.com/xml/confml/2","http://www.s60.com/xml/confml/1"]
    35 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 INCLUDE_NAMESPACES       = ["http://www.w3.org/2001/XInclude","http://www.w3.org/2001/xinclude"]
    36 XLINK_NAMESPACES         = ["http://www.w3.org/1999/xlink"]
    37 XLINK_NAMESPACES         = ["http://www.w3.org/1999/xlink"]
    37 SCHEMA_NAMESPACES        = ["http://www.w3.org/2001/XMLSchema"]
    38 SCHEMA_NAMESPACES        = ["http://www.w3.org/2001/XMLSchema"]
       
    39 RULEML_NAMESPACES        = ["http://www.s60.com/xml/ruleml/3"]
       
    40 RULEML_NAMESPACE         = {"http://www.s60.com/xml/ruleml/3" : "ruleml"}
    38 CV_NAMESPACE             = {"http://www.nokia.com/xml/cpf-id/1": "cv"}
    41 CV_NAMESPACE             = {"http://www.nokia.com/xml/cpf-id/1": "cv"}
       
    42 KNOWN_NAMESPACES         = []
       
    43 KNOWN_NAMESPACES.extend(CONFIGURATION_NAMESPACES)
       
    44 KNOWN_NAMESPACES.extend(INCLUDE_NAMESPACES)
       
    45 KNOWN_NAMESPACES.extend(XLINK_NAMESPACES)
       
    46 KNOWN_NAMESPACES.extend(SCHEMA_NAMESPACES)
       
    47 KNOWN_NAMESPACES.extend(CV_NAMESPACE)
    39 MODEL                    = model
    48 MODEL                    = model
    40 
    49 
    41 def dumps(obj, indent=True):
    50 def dumps(obj, indent=True):
    42     etree = ConfmlWriter().dumps(obj)
    51     etree = ConfmlWriter().dumps(obj)
    43     if indent:
    52     if indent:
   363             elem.set('id', obj.get_id())
   372             elem.set('id', obj.get_id())
   364         if obj.get_relevant() != None:
   373         if obj.get_relevant() != None:
   365             elem.set('relevant', obj.get_relevant())
   374             elem.set('relevant', obj.get_relevant())
   366         if obj.get_constraint() != None:
   375         if obj.get_constraint() != None:
   367             elem.set('constraint', obj.get_constraint())
   376             elem.set('constraint', obj.get_constraint())
       
   377         
       
   378         dump_extension_attributes(obj, elem)
       
   379         
   368         for child in obj._objects():
   380         for child in obj._objects():
   369             """ Make sure that the object is mapped to an object in this model """
   381             """ Make sure that the object is mapped to an object in this model """
   370             mobj = child._get_mapper('confml').map_object(child)
   382             mobj = child._get_mapper('confml').map_object(child)
   371             writer = get_writer_for_class(mobj.__class__.__name__)
   383             writer = get_writer_for_class(mobj.__class__.__name__)
   372             childelem = writer.dumps(child)
   384             childelem = writer.dumps(child)
   406             feature.set_relevant(elem.get('relevant'))
   418             feature.set_relevant(elem.get('relevant'))
   407         if elem.get('constraint') != None:
   419         if elem.get('constraint') != None:
   408             feature.set_constraint(elem.get('constraint'))
   420             feature.set_constraint(elem.get('constraint'))
   409         feature.set_type(type)
   421         feature.set_type(type)
   410         feature.lineno = utils.etree.get_lineno(elem)
   422         feature.lineno = utils.etree.get_lineno(elem)
       
   423         
       
   424         load_extension_attributes(elem, feature)
       
   425         
   411         for elem in elem.getchildren():
   426         for elem in elem.getchildren():
   412             # At the moment we ignore the namespace of elements
   427             # At the moment we ignore the namespace of elements
   413             (namespace,elemname) = get_elemname(elem.tag)
   428             (_,elemname) = get_elemname(elem.tag)
   414             try:
   429             try:
   415                 reader = get_reader_for_elem(elemname)
   430                 reader = get_reader_for_elem(elemname)
   416                 obj = reader.loads(elem)
   431                 obj = reader.loads(elem)
   417                 feature.add(obj)
   432                 feature.add(obj)
   418             except exceptions.ConePersistenceError,e:
   433             except exceptions.ConePersistenceError:
   419                 add_unknown_element_warning(elem)
   434                 add_unknown_element_warning(elem)
   420                 continue
   435                 continue
   421         return feature
   436         return feature
   422 
   437 
   423 
   438 
   444         if obj.map is not None: objdict['map'] = obj.map
   459         if obj.map is not None: objdict['map'] = obj.map
   445         if obj.relevant is not None: objdict['relevant'] = obj.relevant
   460         if obj.relevant is not None: objdict['relevant'] = obj.relevant
   446         if obj.display_name is not None: objdict['displayName'] = obj.display_name
   461         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
   462         if obj.map_value is not None: objdict['mapValue'] = obj.map_value
   448 
   463 
       
   464         if hasattr(obj,'extensionAttributes') and obj.extensionAttributes is not None and obj.extensionAttributes != []:
       
   465             for ext_attribute in obj.extensionAttributes:
       
   466                 if ext_attribute.ns != None and ext_attribute.ns != "":
       
   467                     objdict["{%s}%s" % (ext_attribute.ns, ext_attribute.name)] = str(ext_attribute.value)
       
   468                 else:
       
   469                     objdict[ext_attribute.name] = str(ext_attribute.value)    
       
   470 
   449         elem = ElementTree.Element('option', objdict)
   471         elem = ElementTree.Element('option', objdict)
   450         
   472         
   451         return elem
   473         return elem
   452 
   474 
   453 
   475 
   480             option = api.Option(name, value, map=optmap, 
   502             option = api.Option(name, value, map=optmap, 
   481                                 relevant=elem.get('relevant'),
   503                                 relevant=elem.get('relevant'),
   482                                 map_value=elem.get('mapValue'), 
   504                                 map_value=elem.get('mapValue'), 
   483                                 display_name=elem.get('displayName'))
   505                                 display_name=elem.get('displayName'))
   484             option.lineno = utils.etree.get_lineno(elem) 
   506             option.lineno = utils.etree.get_lineno(elem) 
       
   507             
       
   508         #Add extension attributes
       
   509         for attribute in elem.attrib:
       
   510             (ns,attname) = get_elemname(attribute)
       
   511             if ns != None and ns != "":
       
   512                 if not ns in KNOWN_NAMESPACES:
       
   513                     option.add_extension_attribute(model.ConfmlExtensionAttribute(attname, elem.attrib[attribute], ns))
       
   514         
   485         return option
   515         return option
   486 
   516 
   487 
   517 
   488 class IconWriter(ConfmlWriter):
   518 class IconWriter(ConfmlWriter):
   489     @classmethod
   519     @classmethod
   902             elem.set('mapKey', str(obj.mapKey))
   932             elem.set('mapKey', str(obj.mapKey))
   903         if hasattr(obj,'mapValue') and obj.mapValue is not None:
   933         if hasattr(obj,'mapValue') and obj.mapValue is not None:
   904             elem.set('mapValue', str(obj.mapValue))
   934             elem.set('mapValue', str(obj.mapValue))
   905         if hasattr(obj,'displayName') and obj.displayName is not None:
   935         if hasattr(obj,'displayName') and obj.displayName is not None:
   906             elem.set('displayName', str(obj.displayName))
   936             elem.set('displayName', str(obj.displayName))
       
   937             
       
   938         if getattr(obj, 'extensionAttributes', None):
       
   939             for ext_attribute in obj.extensionAttributes:
       
   940                 if ext_attribute.ns:
       
   941                     elem.set(("{%s}%s" % (ext_attribute.ns, ext_attribute.name)), str(ext_attribute.value))
       
   942                 else:
       
   943                     elem.set(ext_attribute.name, str(ext_attribute.value))
   907             
   944             
   908         for child in obj._objects():
   945         for child in obj._objects():
   909             """ Make sure that the object is mapped to an object in this model """
   946             """ Make sure that the object is mapped to an object in this model """
   910             mobj = child._get_mapper('confml').map_object(child)
   947             mobj = child._get_mapper('confml').map_object(child)
   911             writer = get_writer_for_class(mobj.__class__.__name__)
   948             writer = get_writer_for_class(mobj.__class__.__name__)
   964             feature = model.ConfmlDateTimeSetting(elem.get('ref'))
  1001             feature = model.ConfmlDateTimeSetting(elem.get('ref'))
   965         elif typedef == 'duration':
  1002         elif typedef == 'duration':
   966             feature = model.ConfmlDurationSetting(elem.get('ref'))
  1003             feature = model.ConfmlDurationSetting(elem.get('ref'))
   967         elif typedef == 'hexBinary':
  1004         elif typedef == 'hexBinary':
   968             feature = model.ConfmlHexBinarySetting(elem.get('ref'))
  1005             feature = model.ConfmlHexBinarySetting(elem.get('ref'))
   969         
       
   970            
       
   971         else:
  1006         else:
   972             # Handle the default setting as int type
  1007             # Handle the default setting as int type
   973             feature = model.ConfmlSetting(elem.get('ref'), type=typedef)
  1008             feature = model.ConfmlSetting(elem.get('ref'), type=typedef)
   974         feature.lineno = utils.etree.get_lineno(elem)
  1009         feature.lineno = utils.etree.get_lineno(elem)
   975         self._get_setting_properties(elem, feature)
  1010         self._get_setting_properties(elem, feature)
       
  1011         
   976         return feature
  1012         return feature
   977         
  1013         
   978     def _get_setting_properties(self, elem, feature):
  1014     def _get_setting_properties(self, elem, feature):
   979         """
  1015         """
   980         Get the setting properties for the given feature from the given xml elem
  1016         Get the setting properties for the given feature from the given xml elem
   994         if elem.get('constraint'):
  1030         if elem.get('constraint'):
   995             feature.constraint = elem.get('constraint')
  1031             feature.constraint = elem.get('constraint')
   996         if elem.get('relevant'):
  1032         if elem.get('relevant'):
   997             feature.relevant = elem.get('relevant')
  1033             feature.relevant = elem.get('relevant')
   998         
  1034         
       
  1035         #Add extension attributes
       
  1036         for attribute in elem.attrib:
       
  1037             (ns,attname) = get_elemname(attribute)
       
  1038             if ns != None and ns != "":
       
  1039                 if not ns in KNOWN_NAMESPACES:
       
  1040                     feature.add_extension_attribute(model.ConfmlExtensionAttribute(attname, elem.attrib[attribute], ns))
       
  1041         
   999         for elem in elem.getchildren():
  1042         for elem in elem.getchildren():
  1000             # At the moment we ignore the namespace of elements
  1043             # At the moment we ignore the namespace of elements
  1001             (namespace,elemname) = get_elemname(elem.tag)
  1044             (namespace,elemname) = get_elemname(elem.tag)
  1002             try:
  1045             try:
  1003                 reader = get_reader_for_elem(elemname)
  1046                 reader = get_reader_for_elem(elemname)
  1004                 obj = reader.loads(elem)
  1047                 obj = reader.loads(elem)
       
  1048                     
  1005                 if obj != None:
  1049                 if obj != None:
  1006                     feature.add(obj,container.APPEND)
  1050                     feature.add(obj,container.APPEND)
  1007                 else:
  1051                 else:
  1008                     add_parse_warning("Invalid child %s in %s" % (elem, feature.name),
  1052                     add_parse_warning("Invalid child %s in %s" % (elem, feature.name),
  1009                                       utils.etree.get_lineno(elem))
  1053                                       utils.etree.get_lineno(elem))
  1169             return False
  1213             return False
  1170 
  1214 
  1171     def dumps(self, obj):
  1215     def dumps(self, obj):
  1172         return None
  1216         return None
  1173 
  1217 
  1174 
  1218 class ExtensionsWriter(ConfmlWriter):
       
  1219     @classmethod
       
  1220     def supported_class(cls, classname):
       
  1221         """
       
  1222         Class method to determine if this ConfmlWriter supports writing
       
  1223         of the given class name
       
  1224         """
       
  1225         if classname=="ConfmlExtensions":
       
  1226             return True
       
  1227         else:
       
  1228             return False
       
  1229 
       
  1230     def dumps(self, obj):
       
  1231         """
       
  1232         @param obj: The Configuration object 
       
  1233         """
       
  1234         
       
  1235         elem = ElementTree.Element("extensions")
       
  1236         for extension in obj._objects():
       
  1237             if isinstance(extension, api.RulemlEvalGlobals):
       
  1238                 writer = EvalGlobalsWriter()
       
  1239                 childelem = writer.dumps(extension)
       
  1240                 if childelem != None:
       
  1241                     elem.append(childelem)
       
  1242             else:
       
  1243                 if extension.ns != None and extension.ns != "":
       
  1244                     childelem = ElementTree.Element("{%s}%s" % (extension.ns, extension.tag))
       
  1245                 else:
       
  1246                     childelem = ElementTree.Element(extension.tag)
       
  1247                 if extension.value != None:
       
  1248                     childelem.text = extension.value
       
  1249                 for attr in extension.attrs:
       
  1250                     childelem.set(attr, extension.attrs[attr])
       
  1251                 
       
  1252                 childs = self._dump_childen(extension._objects())
       
  1253                 for ch in childs:
       
  1254                     childelem.append(ch)
       
  1255                 
       
  1256                 elem.append(childelem)
       
  1257         return elem
       
  1258 
       
  1259     def _dump_childen(self, obj):
       
  1260         childs = []
       
  1261         
       
  1262         for child in obj:
       
  1263             if child.ns != None and child.ns != "":
       
  1264                 childelem = ElementTree.Element("{%s}%s" % (child.ns, child.tag))
       
  1265             else:
       
  1266                 childelem = ElementTree.Element(child.tag)
       
  1267             if child.value != None:
       
  1268                 childelem.text = child.value
       
  1269             for attr in child.attrs:
       
  1270                 childelem.set(attr, child.attrs[attr])
       
  1271                 
       
  1272                 
       
  1273             chds = self._dump_childen(child._objects())
       
  1274             for ch in chds:
       
  1275                 childelem.append(ch)
       
  1276                 
       
  1277             childs.append(childelem)
       
  1278             
       
  1279         return childs
       
  1280 #import xml.sax.expatreader 
       
  1281 
       
  1282 class ExtensionsReader(ConfmlReader):
       
  1283     
       
  1284     @classmethod
       
  1285     def supported_elem(cls, elemname, parent=None):
       
  1286         """
       
  1287         Class method to determine if this ConfmlWriter supports reading
       
  1288         of the given elem name
       
  1289         """
       
  1290         if elemname=="extensions":
       
  1291             return True
       
  1292         else:
       
  1293             return False
       
  1294 
       
  1295     def loads(self,etree):
       
  1296         extensionselem = model.ConfmlExtensions()
       
  1297         extensionselem.lineno = utils.etree.get_lineno(etree)
       
  1298         for elem in etree.getchildren():
       
  1299             try:
       
  1300                 (_,elemname) = utils.xml.split_tag_namespace(elem.tag)
       
  1301                 reader = get_reader_for_elem(elemname, 'extensions')
       
  1302             except exceptions.ConePersistenceError:
       
  1303                 extensionselem._add(self._load_children(elem, etree), policy=container.APPEND)
       
  1304             else:
       
  1305                 obj = reader.loads(elem)
       
  1306                 if obj != None:
       
  1307                     extensionselem._add(obj, policy=container.APPEND)
       
  1308         return extensionselem
       
  1309 
       
  1310     def _load_children(self, elem, etree):
       
  1311         (namespace,elemname) = get_elemname(elem.tag)
       
  1312         attributes = {}
       
  1313         for key in elem.keys():
       
  1314             attributes[key] = elem.get(key)
       
  1315 
       
  1316         extension = model.ConfmlExtension(elemname, elem.text, namespace, attrs=attributes)
       
  1317         
       
  1318         for childelem in elem.getchildren():
       
  1319             extension._add(self._load_children(childelem, etree), policy=container.APPEND)
       
  1320         
       
  1321         return extension
       
  1322         
       
  1323 
       
  1324 class EvalGlobalsWriter(ConfmlWriter):
       
  1325     @classmethod
       
  1326     def supported_class(cls, classname):
       
  1327         """
       
  1328         Class method to determine if this ConfmlWriter supports writing
       
  1329         of the given class name
       
  1330         """
       
  1331         if classname=="RulemlEvalGlobals":
       
  1332             return True
       
  1333         else:
       
  1334             return False
       
  1335 
       
  1336     def dumps(self, obj):
       
  1337         """
       
  1338         @param obj: The Configuration object 
       
  1339         """
       
  1340         
       
  1341         elem = ElementTree.Element("{%s}eval_globals" % (RULEML_NAMESPACES[0]))
       
  1342 
       
  1343         if obj.value != None:
       
  1344             elem.text = obj.value
       
  1345         if obj.file != None:
       
  1346             elem.set('file', obj.file)
       
  1347         
       
  1348         return elem
       
  1349 
       
  1350 class EvalGlobalsReader(ConfmlReader):
       
  1351     
       
  1352     @classmethod
       
  1353     def supported_elem(cls, elemname, parent=None):
       
  1354         """
       
  1355         Class method to determine if this ConfmlWriter supports reading
       
  1356         of the given elem name
       
  1357         """
       
  1358         if elemname=="eval_globals":
       
  1359             return True
       
  1360         else:
       
  1361             return False
       
  1362 
       
  1363     def loads(self,etree):
       
  1364         eval_globals = api.RulemlEvalGlobals(etree.text, etree.get("file", None))
       
  1365         
       
  1366         return eval_globals
  1175 
  1367 
  1176 class RfsReader(ConfmlReader):
  1368 class RfsReader(ConfmlReader):
  1177     """
  1369     """
  1178     """ 
  1370     """ 
  1179     @classmethod
  1371     @classmethod
  1253         namespace = ""
  1445         namespace = ""
  1254         elemname = nn.group(1)
  1446         elemname = nn.group(1)
  1255         return (namespace,elemname)
  1447         return (namespace,elemname)
  1256     else:
  1448     else:
  1257         raise exceptions.ParseError("Could not parse tag %s" % tag)
  1449         raise exceptions.ParseError("Could not parse tag %s" % tag)
  1258         
       
  1259 
  1450 
  1260 def get_reader_for_elem(elemname, parent=None):
  1451 def get_reader_for_elem(elemname, parent=None):
  1261     for reader in utils.all_subclasses(ConfmlReader):
  1452     for reader in utils.all_subclasses(ConfmlReader):
  1262         if reader.supported_elem(elemname,parent):
  1453         if reader.supported_elem(elemname,parent):
  1263             return reader()
  1454             return reader()
  1266 def get_writer_for_class(classname):
  1457 def get_writer_for_class(classname):
  1267     for writer in utils.all_subclasses(ConfmlWriter):
  1458     for writer in utils.all_subclasses(ConfmlWriter):
  1268         if writer.supported_class(classname):
  1459         if writer.supported_class(classname):
  1269             return writer ()
  1460             return writer ()
  1270     raise exceptions.ConePersistenceError("No writer for given class found! %s" % classname)
  1461     raise exceptions.ConePersistenceError("No writer for given class found! %s" % classname)
       
  1462 
       
  1463 def dump_extension_attributes(obj, elem):
       
  1464     if hasattr(obj,'extensionAttributes') and obj.extensionAttributes is not None and obj.extensionAttributes != []:
       
  1465         for ext_attribute in obj.extensionAttributes:
       
  1466             if ext_attribute.ns != None and ext_attribute.ns != "":
       
  1467                 elem.set(("{%s}%s" % (ext_attribute.ns, ext_attribute.name)), unicode(ext_attribute.value))
       
  1468             else:
       
  1469                 elem.set(ext_attribute.name, unicode(ext_attribute.value))    
       
  1470 
       
  1471 def load_extension_attributes(elem, obj):
       
  1472     for attribute in elem.attrib:
       
  1473         (ns,attname) = get_elemname(attribute)
       
  1474         if ns != None and ns != "":
       
  1475             if not ns in KNOWN_NAMESPACES:
       
  1476                 obj.add_extension_attribute(model.ConfmlExtensionAttribute(attname, elem.attrib[attribute], ns))