configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/crml_reader.py
changeset 0 2e8eeb919028
child 3 e7e0ae78773e
equal deleted inserted replaced
-1:000000000000 0:2e8eeb919028
       
     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 
       
    17 from cone.public import exceptions, plugin
       
    18 import crml_impl
       
    19 from crml_model import *
       
    20 
       
    21 
       
    22 def get_required_attr(elem, attrname):
       
    23     """
       
    24     Get a required attribute from an XML element or raise an exception.
       
    25     """
       
    26     attr = elem.get(attrname)
       
    27     if attr is None:
       
    28         raise exceptions.ParseError("<%s> element does not have the required '%s' attribute!" % (elem.tag, attrname))
       
    29     return attr
       
    30 
       
    31 def convert_num(string):
       
    32     """
       
    33     Convert the given string into a number.
       
    34     
       
    35     - The number can be in decimal or hexadecimal format.
       
    36     - If None is passed, None is also returned.
       
    37     """
       
    38     if string in ('', None):
       
    39         return None
       
    40     try:
       
    41         return long(string)
       
    42     except ValueError:
       
    43         return long(string, 16)
       
    44 
       
    45 class CrmlReader(plugin.ReaderBase):
       
    46     NAMESPACE = 'http://www.s60.com/xml/cenrep/1'
       
    47     FILE_EXTENSIONS = ['crml']
       
    48     
       
    49     @classmethod
       
    50     def read_impl(cls, resource_ref, configuration, etree):
       
    51         reader = CrmlReader()
       
    52         repository = reader.read_repository(etree)
       
    53         return crml_impl.CrmlImpl(resource_ref, configuration, repository)
       
    54     
       
    55     def read_repository(self, elem):
       
    56         """
       
    57         Read a CrmlRepository object from the given XML element.
       
    58         """
       
    59         # Read repository attributes
       
    60         repo = CrmlRepository(
       
    61             uid_value = elem.get('uidValue'),
       
    62             uid_name  = elem.get('uidName'),
       
    63             owner     = elem.get('owner'),
       
    64             version   = elem.get('initialisationFileVersion', '1'),
       
    65             access    = self.read_access(elem))
       
    66         if elem.get('backup') == 'true':    repo.backup = True
       
    67         if elem.get('rfs') == 'true':       repo.rfs = True
       
    68         
       
    69         # Read all keys
       
    70         for sub_elem in elem:
       
    71             key_obj = self.read_key(sub_elem)
       
    72             
       
    73             if key_obj is not None:
       
    74                 # Read-only keys have always cap_wr=AlwaysFail.
       
    75                 # the isinstance() check is for CT2 output compatibility
       
    76                 if not isinstance(key_obj, CrmlKeyRange):
       
    77                     if key_obj.read_only:
       
    78                         key_obj.access.cap_wr = 'AlwaysFail'
       
    79                         key_obj.access.sid_wr = None
       
    80                 
       
    81                 repo.keys.append(key_obj)
       
    82         
       
    83         if repo.access == CrmlAccess(cap_rd='AlwaysPass') and len(repo.keys) == 0:
       
    84             repo.access.cap_rd = None
       
    85         
       
    86         return repo
       
    87     
       
    88     def read_access(self, elem):
       
    89         """
       
    90         Read a CrmlAccess object from the given XML element.
       
    91         @param elem: The element from which to parse an access definition. Should be any
       
    92             element that can contain an access definition (i.e. 'repository', 'key', or 'keyRange').
       
    93         """
       
    94         access = CrmlAccess()
       
    95         read_cap_found = False
       
    96         write_cap_found = False
       
    97         for access_elem in elem.findall('{%s}access' % self.NAMESPACE):
       
    98             type = access_elem.get('type')
       
    99             if type == 'R' and not read_cap_found:
       
   100                 access.cap_rd = access_elem.get('capabilities')
       
   101                 access.sid_rd = access_elem.get('sid')
       
   102                 read_cap_found = True
       
   103             elif type == 'W' and not write_cap_found:
       
   104                 access.cap_wr = access_elem.get('capabilities')
       
   105                 access.sid_wr = access_elem.get('sid')
       
   106                 write_cap_found = True
       
   107         
       
   108         return access
       
   109     
       
   110     def read_common_key_attrs(self, key_elem, key_obj):
       
   111         """
       
   112         Read common attributes into an object of class CrmlKeyBase from an XML element.
       
   113         """
       
   114         if not isinstance(key_obj, CrmlKeyBase):
       
   115             raise ValueError("Expected object of type %s" % CrmlKeyBase.__name__)
       
   116         
       
   117         if key_elem.get('readOnly') == 'true':  key_obj.read_only = True
       
   118         if key_elem.get('backup') == 'true':    key_obj.backup = True
       
   119         key_obj.access = self.read_access(key_elem)
       
   120         key_obj.name = key_elem.get('name')
       
   121     
       
   122     def read_key(self, key_elem):
       
   123         key_obj = None
       
   124         if key_elem.tag == '{%s}key' % self.NAMESPACE:
       
   125             # Determine whether the key is a normal key or a bitmask key
       
   126             # based on the presence of <bit> elements
       
   127             tags = [e.tag for e in key_elem]
       
   128             if '{%s}bit' % self.NAMESPACE in tags:
       
   129                 key_obj = self.read_bitmask_key(key_elem)
       
   130             else:
       
   131                 key_obj = self.read_simple_key(key_elem)
       
   132         elif key_elem.tag == '{%s}keyRange' % self.NAMESPACE:
       
   133             key_obj = self.read_key_range(key_elem)
       
   134         
       
   135         return key_obj
       
   136     
       
   137     def read_simple_key(self, key_elem):
       
   138         """
       
   139         Read a CrmlSimpleKey object from the given XML element.
       
   140         """
       
   141         expected_tag = '{%s}key' % self.NAMESPACE
       
   142         if key_elem.tag != expected_tag:
       
   143             raise RuntimeError("Incorrect XML element passed to read_simple_key(): %s, expected %s" % (key_elem.tag, expected_tag))
       
   144         
       
   145         key = CrmlSimpleKey(
       
   146             ref  = get_required_attr(key_elem, 'ref').replace('/', '.'),
       
   147             int  = get_required_attr(key_elem, 'int'),
       
   148             type = key_elem.get('type', 'int'))
       
   149         self.read_common_key_attrs(key_elem, key)
       
   150         
       
   151         return key
       
   152     
       
   153     def read_bitmask_key(self, key_elem):
       
   154         """
       
   155         Read a CrmlBitmaskKey object from the given XML element.
       
   156         """
       
   157         expected_tag = '{%s}key' % self.NAMESPACE
       
   158         if key_elem.tag != expected_tag:
       
   159             raise RuntimeError("Incorrect XML element passed to read_bitmask_key(): %s, expected %s" % (key_elem.tag, expected_tag))
       
   160         
       
   161         # Read attributes
       
   162         key = CrmlBitmaskKey(
       
   163             int  = get_required_attr(key_elem, 'int'),
       
   164             type = key_elem.get('type', 'int'))
       
   165         self.read_common_key_attrs(key_elem, key)
       
   166         
       
   167         # Read bits
       
   168         for bit_elem in key_elem.findall('{%s}bit' % self.NAMESPACE):
       
   169             ref = get_required_attr(bit_elem, 'ref').replace('/', '.')
       
   170             if bit_elem.get('value') == 'false':    invert = True
       
   171             else:                                   invert = False
       
   172             index = int(bit_elem.text.strip())
       
   173             
       
   174             key.bits.append(CrmlBit(ref=ref, index=index, type=type, invert=invert))
       
   175         
       
   176         return key
       
   177     
       
   178     def read_key_range(self, key_range_elem):
       
   179         """
       
   180         Read a CrmlKeyRange object from the given XML element.
       
   181         """
       
   182         expected_tag = '{%s}keyRange' % self.NAMESPACE
       
   183         if key_range_elem.tag != expected_tag:
       
   184             raise RuntimeError("Incorrect XML element passed to read_key_range(): %s, expected %s" % (key_range_elem.tag, expected_tag))
       
   185         
       
   186         # Read attributes
       
   187         ref = key_range_elem.get('ref')
       
   188         if ref is not None: ref = ref.replace('/', '.')
       
   189         key_range = CrmlKeyRange(
       
   190             ref         = ref,
       
   191             first_int   = get_required_attr(key_range_elem, "firstInt"),
       
   192             last_int    = get_required_attr(key_range_elem, "lastInt"),
       
   193             count_int   = key_range_elem.get('countInt'),
       
   194             first_index = convert_num(key_range_elem.get('firstIndex', '0')),
       
   195             index_bits  = convert_num(key_range_elem.get('indexBits')))
       
   196         self.read_common_key_attrs(key_range_elem, key_range)
       
   197         
       
   198         # Read sub-keys
       
   199         for subkey_elem in key_range_elem.findall('{%s}key' % self.NAMESPACE):
       
   200             ref = get_required_attr(subkey_elem, 'ref').replace('/', '.')
       
   201             int = get_required_attr(subkey_elem, 'int')
       
   202             name = subkey_elem.get('name')
       
   203             type = subkey_elem.get('type', 'int')
       
   204             key_range.subkeys.append(CrmlKeyRangeSubKey(ref=ref, int=int, name=name, type=type))
       
   205         
       
   206         return key_range