configurationengine/source/cone/confml/model.py
changeset 3 e7e0ae78773e
parent 0 2e8eeb919028
child 5 d2c80f5cab53
equal deleted inserted replaced
2:87cfa131b535 3:e7e0ae78773e
    19 Base class for Confml elements.
    19 Base class for Confml elements.
    20 Attributes:
    20 Attributes:
    21  All Confml element attributes become attributes of this instance.
    21  All Confml element attributes become attributes of this instance.
    22 """
    22 """
    23 import types
    23 import types
       
    24 import sys
       
    25 import re
    24 from cone.public import api, exceptions, container, utils
    26 from cone.public import api, exceptions, container, utils
    25 
    27 
    26 class ConfmlElement(api.Base):
    28 class ConfmlElement(api.Base):
       
    29     def __init__(self, ref="", **kwargs):
       
    30         super(ConfmlElement,self).__init__(ref, **kwargs)
       
    31         self.lineno = None
       
    32 
    27     def _get_mapper(self,modelname):
    33     def _get_mapper(self,modelname):
    28         """
    34         """
    29         Return a instance of appropriate mapper for given model.
    35         Return a instance of appropriate mapper for given model.
    30         """
    36         """
    31         mapmodule = __import__('cone.confml.mapping')
    37         mapmodule = __import__('cone.confml.mapping')
    46             self._remove(ConfmlDescription.refname)
    52             self._remove(ConfmlDescription.refname)
    47         except exceptions.NotFound:
    53         except exceptions.NotFound:
    48             pass
    54             pass
    49     """ The description as a property """
    55     """ The description as a property """
    50     desc = property(get_desc,set_desc,del_desc)
    56     desc = property(get_desc,set_desc,del_desc)
       
    57     
       
    58 class ConfmlData(api.Data):
       
    59     """
       
    60     The data element can contain any data setting for a feature. The data element can be 
       
    61     a value definition for any type of data. It basically just links some data to a feature. 
       
    62     The default Data attribute is 'data', but it can be any string. For example current use case 
       
    63     is 'rfs'.
       
    64     """
       
    65     def __init__(self, **kwargs):
       
    66         super(ConfmlData,self).__init__(**kwargs)
       
    67         self.lineno = None
       
    68 
    51 class ConfmlConfiguration(ConfmlElement, api.Configuration):
    69 class ConfmlConfiguration(ConfmlElement, api.Configuration):
    52     """
    70     """
    53     Confml configuration class. 
    71     Confml configuration class. 
    54     """
    72     """
    55     def __init__(self,ref="", **kwargs):
    73     def __init__(self,ref="", **kwargs):
    57         if kwargs.get('meta'):
    75         if kwargs.get('meta'):
    58             self.meta = kwargs.get('meta')
    76             self.meta = kwargs.get('meta')
    59         if kwargs.get('desc'):
    77         if kwargs.get('desc'):
    60             self.desc = kwargs.get('desc')
    78             self.desc = kwargs.get('desc')
    61 
    79 
       
    80     def _view_class(self):
       
    81         return ConfmlView
       
    82 
       
    83     def _feature_class(self):
       
    84         return ConfmlFeature
       
    85 
       
    86     def _configuration_class(self):
       
    87         return ConfmlConfiguration
    62 
    88 
    63     def get_desc(self): 
    89     def get_desc(self): 
    64         """
    90         """
    65         @return: The description of the Configuration.
    91         @return: The description of the Configuration.
    66         """
    92         """
    82     """ The description as a property """
   108     """ The description as a property """
    83     desc = property(get_desc,set_desc,del_desc)
   109     desc = property(get_desc,set_desc,del_desc)
    84 
   110 
    85     def get_meta(self): 
   111     def get_meta(self): 
    86         """
   112         """
    87         @return: The description of the Configuration.
   113         @return: The meta element of the Configuration.
    88         """
   114         """
    89         try:
   115         try:
    90             meta = getattr(self,ConfmlMeta.refname)
   116             meta = getattr(self,ConfmlMeta.refname)
    91             return meta
   117             return meta
    92         except AttributeError:
   118         except AttributeError:
   102             pass
   128             pass
   103 
   129 
   104     """ The meta element as a property """
   130     """ The meta element as a property """
   105     meta = property(get_meta,set_meta,del_meta)
   131     meta = property(get_meta,set_meta,del_meta)
   106 
   132 
   107 
   133 class ConfmlSettingAttributes(ConfmlElement):
   108 class ConfmlGroup(ConfmlElement, api.Group):
   134     """
   109     """
   135     Abstract base class for setting attributes. This is used as 
   110     Confml view.
   136     a base in actual ConfmlSetting and ConfmlFeatureLink.
   111     """
   137     """
   112     def __init__(self, ref="", **kwargs):
   138     def __init__(self, ref,**kwargs):
   113         super(ConfmlGroup,self).__init__(ref,**kwargs)
   139         super(ConfmlSettingAttributes,self).__init__(ref,**kwargs)
   114         if kwargs.get('icon'):
       
   115             self.icon = kwargs.get('icon')
       
   116         if kwargs.get('desc'):
       
   117             self.desc = kwargs.get('desc')
       
   118 
       
   119     def get_icon(self): 
       
   120         try:
       
   121             icon = getattr(self,ConfmlIcon.refname)
       
   122             return icon.href
       
   123         except AttributeError:
       
   124             return None
       
   125     def set_icon(self,value): self._add(ConfmlIcon(value))
       
   126     def del_icon(self): 
       
   127         try:
       
   128             self._remove(ConfmlIcon.refname)
       
   129         except exceptions.NotFound:
       
   130             pass
       
   131     """ The icon as a property """
       
   132     icon = property(get_icon,set_icon,del_icon)
       
   133 
       
   134     def get_desc(self): 
       
   135         try:
       
   136             desc = getattr(self,ConfmlDescription.refname)
       
   137             return desc.text
       
   138         except AttributeError:
       
   139             return None
       
   140     def set_desc(self,value): self._add(ConfmlDescription(value))
       
   141     def del_desc(self): 
       
   142         try:
       
   143             self._remove(ConfmlDescription.refname)
       
   144         except exceptions.NotFound:
       
   145             pass
       
   146     """ The description as a property """
       
   147     desc = property(get_desc,set_desc,del_desc)
       
   148 
       
   149 
       
   150 class ConfmlView(api.View):
       
   151     """
       
   152     Confml view.
       
   153     """
       
   154     def __init__(self, ref="", **kwargs):
       
   155         super(ConfmlView,self).__init__(ref,**kwargs)
       
   156         if kwargs.get('desc'):
       
   157             self.desc = kwargs.get('desc')
       
   158 
       
   159 
       
   160     def get_desc(self): 
       
   161         try:
       
   162             desc = getattr(self,ConfmlDescription.refname)
       
   163             return desc.text
       
   164         except AttributeError:
       
   165             return None
       
   166     def set_desc(self,value): self._add(ConfmlDescription(value))
       
   167     def del_desc(self): 
       
   168         try:
       
   169             self._remove(ConfmlDescription.refname)
       
   170         except exceptions.NotFound:
       
   171             pass
       
   172     """ The description as a property """
       
   173     desc = property(get_desc,set_desc,del_desc)
       
   174 
       
   175 class ConfmlFeature(ConfmlElement, api.Feature):
       
   176     pass
       
   177 
       
   178 class ConfmlSetting(ConfmlElement, api.Feature):
       
   179     """
       
   180     Confml setting class. Attribute 'options' contains options of this setting.
       
   181     """
       
   182     supported_types = ['int',
       
   183                        'string',
       
   184                        'boolean',
       
   185                        'selection']
       
   186     def __init__(self, ref,**kwargs):
       
   187         super(ConfmlSetting,self).__init__(ref,**kwargs)
       
   188         self.type = kwargs.get('type',None)
       
   189         if kwargs.get('desc'):
   140         if kwargs.get('desc'):
   190             self.desc = kwargs.get('desc')
   141             self.desc = kwargs.get('desc')
   191         if kwargs.get('minOccurs'):
   142         if kwargs.get('minOccurs'):
   192             self.minOccurs = kwargs.get('minOccurs')
   143             self.minOccurs = kwargs.get('minOccurs')
   193         if kwargs.get('maxOccurs'):
   144         if kwargs.get('maxOccurs'):
   194             self.maxOccurs = kwargs.get('maxOccurs')
   145             self.maxOccurs = kwargs.get('maxOccurs')
   195         if kwargs.get('maxLength'):
   146         if kwargs.get('maxLength'):
   196             self.maxLength = kwargs.get('maxLength')
   147             self.maxLength = kwargs.get('maxLength')
   197         if kwargs.get('minLength'):
   148         if kwargs.get('minLength'):
   198             self.minLength = kwargs.get('minLength')
   149             self.minLength = kwargs.get('minLength')
   199         if kwargs.get('mapKey'):
   150         self.mapKey = kwargs.get('mapKey')
   200             self.mapKey = kwargs.get('mapKey')
   151         self.mapValue = kwargs.get('mapValue')
   201         if kwargs.get('mapValue'):
   152         self.displayName = kwargs.get('displayName')
   202             self.mapValue = kwargs.get('mapValue')
   153 
   203         
   154         
   204         self.readOnly = kwargs.get('readOnly',None)
   155         self.readOnly = kwargs.get('readOnly',None)
   205         self.constraint = kwargs.get('constraint',None)
   156         self.constraint = kwargs.get('constraint',None)
   206         self.required = kwargs.get('required',None)
   157         self.required = kwargs.get('required',None)
   207         self.relevant = kwargs.get('relevant',None)
   158         self.relevant = kwargs.get('relevant',None)
   210         """
   161         """
   211         Get the ValueSet object for this feature, that has the list of available values.
   162         Get the ValueSet object for this feature, that has the list of available values.
   212         """
   163         """
   213         return api.ValueRe('.*')
   164         return api.ValueRe('.*')
   214 
   165 
   215     def add_property(self, **kwargs):
       
   216         """
       
   217         @param name=str: property name 
       
   218         @param value=str: property value
       
   219         @param unit=str: property unit, e.g. kB
       
   220         """
       
   221         self._add(ConfmlProperty(**kwargs), container.APPEND)
       
   222 
       
   223     def get_property(self, name):
       
   224         """
       
   225         @param name: The name of the property
       
   226         """
       
   227         for property in utils.get_list(self._get(ConfmlProperty.refname)):
       
   228             if property.name == name:
       
   229                 return property
       
   230         raise exceptions.NotFound("ConfmlProperty with name %s not found!" % name)
       
   231 
       
   232     def remove_property(self, name):
       
   233         """
       
   234         remove a given option from this feature by name. 
       
   235         @param name: 
       
   236         """
       
   237         for property in self._get(ConfmlProperty.refname):
       
   238             if property.name == name:
       
   239                 return self._remove(property.get_fullref())
       
   240         raise exceptions.NotFound("ConfmlProperty with name %s not found!" % name)
       
   241 
       
   242     def list_properties(self):
       
   243         """
       
   244         Return a array of all Feature children references under this object.
       
   245         """
       
   246         return [obj.name for obj in utils.get_list(self._get(ConfmlProperty.refname))]
       
   247 
       
   248     def get_maxlength(self): 
   166     def get_maxlength(self): 
   249         try:
   167         try:
   250             return getattr(self,ConfmlMaxLength.refname).value
   168             return getattr(self,ConfmlMaxLength.refname).value
   251         except AttributeError:
   169         except AttributeError:
   252             return None
   170             return None
   257     def del_maxlength(self): 
   175     def del_maxlength(self): 
   258         try:
   176         try:
   259             self._remove(ConfmlMaxLength.refname)
   177             self._remove(ConfmlMaxLength.refname)
   260         except exceptions.NotFound:
   178         except exceptions.NotFound:
   261             pass
   179             pass
   262     """ The description as a property """
   180     """ The maxLength as a property """
   263     maxLength = property(get_maxlength,set_maxlength,del_maxlength)
   181     maxLength = property(get_maxlength,set_maxlength,del_maxlength)
   264 
   182 
   265     def get_minlength(self): 
   183     def get_minlength(self): 
   266         try:
   184         try:
   267             return getattr(self,ConfmlMinLength.refname).value
   185             return getattr(self,ConfmlMinLength.refname).value
   274     def del_minlength(self): 
   192     def del_minlength(self): 
   275         try:
   193         try:
   276             self._remove(ConfmlMinLength.refname)
   194             self._remove(ConfmlMinLength.refname)
   277         except exceptions.NotFound:
   195         except exceptions.NotFound:
   278             pass
   196             pass
   279     """ The description as a property """
   197     """ The minLength as a property """
   280     minLength = property(get_minlength,set_minlength,del_minlength)
   198     minLength = property(get_minlength,set_minlength,del_minlength)
       
   199     
       
   200     def get_length(self): 
       
   201         try:
       
   202             return getattr(self,ConfmlLength.refname).value
       
   203         except AttributeError:
       
   204             return None
       
   205 
       
   206     def set_length(self,value): 
       
   207         self._add(ConfmlLength(value))
       
   208 
       
   209     def del_length(self): 
       
   210         try:
       
   211             self._remove(ConfmlLength.refname)
       
   212         except exceptions.NotFound:
       
   213             pass
       
   214     """ The length as a property """
       
   215     length = property(get_length,set_length,del_length)
   281 
   216 
   282     def get_minInclusive(self): 
   217     def get_minInclusive(self): 
   283         try:
   218         try:
   284             return getattr(self,ConfmlMinInclusive.refname).value
   219             return getattr(self,ConfmlMinInclusive.refname).value
   285         except AttributeError:
   220         except AttributeError:
   388             optdict[opt.value] = opt
   323             optdict[opt.value] = opt
   389         return  optdict
   324         return  optdict
   390 
   325 
   391     @property
   326     @property
   392     def properties(self):
   327     def properties(self):
   393         dict = {}
   328         propdict = {}
   394         for property in utils.get_list(self._get(ConfmlProperty.refname)):
   329         for prop in self._objects(type=api.Property):
   395             dict[property.name] = property
   330             propdict[prop.name] = prop
   396         return  dict
   331         return  propdict
   397 
   332 
   398     def get_rfs(self,):
   333     def get_rfs(self):
   399         return super(ConfmlSetting,self).get_value('rfs')
   334         return super(ConfmlSettingAttributes,self).get_value('rfs')
   400 
   335 
   401     def set_rfs(self, value):
   336     def set_rfs(self, value):
   402         super(ConfmlSetting,self).set_value('rfs',value)
   337         super(ConfmlSettingAttributes,self).set_value('rfs',value)
   403 
   338 
   404     def del_rfs(self):
   339     def del_rfs(self):
   405         super(ConfmlSetting,self).del_value('rfs')
   340         super(ConfmlSettingAttributes,self).del_value('rfs')
   406 
   341 
   407     rfs = property(get_rfs,set_rfs,del_rfs)
   342     rfs = property(get_rfs,set_rfs,del_rfs)
       
   343 
       
   344 
       
   345 class ConfmlGroup(ConfmlElement, api.Group):
       
   346     """
       
   347     Confml view.
       
   348     """
       
   349     def __init__(self, ref="", **kwargs):
       
   350         super(ConfmlGroup,self).__init__(ref,**kwargs)
       
   351         if kwargs.get('icon'):
       
   352             self.icon = kwargs.get('icon')
       
   353         if kwargs.get('desc'):
       
   354             self.desc = kwargs.get('desc')
       
   355 
       
   356     def _group_class(self):
       
   357         return ConfmlGroup
       
   358 
       
   359     def _featurelink_class(self):
       
   360         return ConfmlFeatureLink
       
   361 
       
   362     def get_icon(self): 
       
   363         try:
       
   364             icon = getattr(self,ConfmlIcon.refname)
       
   365             return icon.href
       
   366         except AttributeError:
       
   367             return None
       
   368     def set_icon(self,value): self._add(ConfmlIcon(value))
       
   369     def del_icon(self): 
       
   370         try:
       
   371             self._remove(ConfmlIcon.refname)
       
   372         except exceptions.NotFound:
       
   373             pass
       
   374     """ The icon as a property """
       
   375     icon = property(get_icon,set_icon,del_icon)
       
   376 
       
   377     def get_desc(self): 
       
   378         try:
       
   379             desc = getattr(self,ConfmlDescription.refname)
       
   380             return desc.text
       
   381         except AttributeError:
       
   382             return None
       
   383     def set_desc(self,value): self._add(ConfmlDescription(value))
       
   384     def del_desc(self): 
       
   385         try:
       
   386             self._remove(ConfmlDescription.refname)
       
   387         except exceptions.NotFound:
       
   388             pass
       
   389     """ The description as a property """
       
   390     desc = property(get_desc,set_desc,del_desc)
       
   391 
       
   392 
       
   393 class ConfmlView(api.View, ConfmlGroup):
       
   394     """
       
   395     Confml view.
       
   396     """
       
   397     def __init__(self, ref="", **kwargs):
       
   398         super(ConfmlView,self).__init__(ref,**kwargs)
       
   399         if kwargs.get('desc'):
       
   400             self.desc = kwargs.get('desc')
       
   401     
       
   402     def get_desc(self): 
       
   403         try:
       
   404             desc = getattr(self,ConfmlDescription.refname)
       
   405             return desc.text
       
   406         except AttributeError:
       
   407             return None
       
   408     def set_desc(self,value): self._add(ConfmlDescription(value))
       
   409     def del_desc(self): 
       
   410         try:
       
   411             self._remove(ConfmlDescription.refname)
       
   412         except exceptions.NotFound:
       
   413             pass
       
   414     """ The description as a property """
       
   415     desc = property(get_desc,set_desc,del_desc)
       
   416 
       
   417 
       
   418 class ConfmlFeature(ConfmlElement, api.Feature):
       
   419     def _feature_class(self):
       
   420         return ConfmlSetting
       
   421 
       
   422 class ConfmlSetting(ConfmlSettingAttributes, api.Feature):
       
   423     """
       
   424     Confml setting class. Attribute 'options' contains options of this setting.
       
   425     """
       
   426     supported_types = ['int',
       
   427                        'string',
       
   428                        'boolean',
       
   429                        'selection']
       
   430     def __init__(self, ref,**kwargs):
       
   431         super(ConfmlSetting,self).__init__(ref,**kwargs)
       
   432         self.type = kwargs.get('type',None)
   408 
   433 
   409     def get_value_cast(self, value, attr=None):
   434     def get_value_cast(self, value, attr=None):
   410         """
   435         """
   411         A function to perform the value type casting in get operation  
   436         A function to perform the value type casting in get operation  
   412         @param value: the value to cast 
   437         @param value: the value to cast 
   423         """
   448         """
   424         A function to perform the value type casting in the set operation  
   449         A function to perform the value type casting in the set operation  
   425         @param value: the value to cast 
   450         @param value: the value to cast 
   426         @param attr: the attribute which is fetched from model (normally in confml either None='data' or 'rfs')
   451         @param attr: the attribute which is fetched from model (normally in confml either None='data' or 'rfs')
   427         """
   452         """
       
   453         # Add a exception case for None value, because the data casting will always fail for it
       
   454         if value == None:
       
   455             return value
       
   456         
   428         if not attr or attr == 'data':
   457         if not attr or attr == 'data':
   429             return self.set_data_cast(value)
   458             return self.set_data_cast(value)
   430         elif attr == 'rfs':
   459         elif attr == 'rfs':
   431             return self.set_rfs_cast(value)
   460             return self.set_rfs_cast(value)
   432         else:
   461         else:
   433             return value
   462             return value
   434 
   463         
   435     def get_data_cast(self, value):
   464     def get_data_cast(self, value):
   436         """
   465         """
   437         A function to perform the data type casting in get operation  
   466         A function to perform the data type casting in get operation  
   438         @param value: the value to cast 
   467         @param value: the value to cast 
   439         """
   468         """
   598 
   627 
   599 class ConfmlMultiSelectionSetting(ConfmlSetting):
   628 class ConfmlMultiSelectionSetting(ConfmlSetting):
   600     """
   629     """
   601     Confml setting class for multiSelection type.
   630     Confml setting class for multiSelection type.
   602     """
   631     """
   603 
   632     
       
   633     # Pattern for checking whether a data value should be interpreted
       
   634     # in the old style (e.g. '"opt1" "opt2" "opt3"')
       
   635     OLD_STYLE_DATA_PATTERN = re.compile(r'"[^"]*([^"]*" ")*[^"]*"')
       
   636     
   604     def __init__(self, ref,**kwargs):
   637     def __init__(self, ref,**kwargs):
   605         kwargs['type'] = 'multiSelection'
   638         kwargs['type'] = 'multiSelection'
   606         ConfmlSetting.__init__(self,ref,**kwargs)
   639         ConfmlSetting.__init__(self,ref,**kwargs)
   607         
   640         
   608 
   641     def add_data(self, data):
       
   642         """
       
   643         Add a data value.
       
   644         @param data: A Data object  
       
   645         """
       
   646         # If there are existing data objects added to the proxy, and they
       
   647         # are not in the same DataContainer (ConfML data section), change the
       
   648         # policy to replace
       
   649         if self.dataproxy.datas.get(data.attr):
       
   650             existing_data_obj = self.dataproxy.datas[data.attr][-1]
       
   651             existing_obj_parent = existing_data_obj._find_parent_or_default(type=api.DataContainer)
       
   652             new_obj_parent = data._find_parent_or_default(type=api.DataContainer)
       
   653             
       
   654             if existing_obj_parent is not new_obj_parent:
       
   655                 self.dataproxy.datas[data.attr] = []
       
   656         
       
   657         self.dataproxy._add_data(data)
       
   658     
   609     def get_valueset(self):
   659     def get_valueset(self):
   610         """
   660         """
   611         Get the ValueSet object for this feature, that has the list of available values.
   661         Get the ValueSet object for this feature, that has the list of available values.
   612         """
   662         """
   613         return api.Feature.get_valueset(self)
   663         return api.Feature.get_valueset(self)
   614 
   664     
   615     def get_data_cast(self, value):
   665     def convert_data_to_value(self, data_objects, cast=True, attr=None):
   616         """
   666         if len(data_objects) == 1:
   617         A function to perform the value type casting in get operation  
   667             d = data_objects[0]
   618         """
   668             
   619         try:
   669             # Special handling for cases where the data is in the old format
   620             if not isinstance(value, types.ListType):
   670             # (pre-2.88 ConfML spec)
   621                 values = value.split('" "')
   671             if d.value is not None:
   622                 for i in range(len(values)):
   672                 if self.OLD_STYLE_DATA_PATTERN.match(d.value):
   623                     if values[i].startswith('"'):
   673                     return tuple([v.rstrip('"').lstrip('"') for v in d.value.split('" "')])
   624                         values[i] = values[i][1:] 
   674             
   625                     if values[i].endswith('"'):
   675             # Single data object with empty="true" means that nothing is selected
   626                         values[i] = values[i][:-1]
   676             if d.empty: return ()
   627                 return values
   677         
   628             return value
   678         # Read each data value (or name-ID mapped value) into result
   629         except AttributeError:
   679         result = []
   630             return None
   680         for data_obj in data_objects:
   631     
   681             if data_obj.map:
   632     def set_data_cast(self, value):
   682                 value = self._resolve_name_id_mapped_value(data_obj.map, cast_value=cast)
   633         """
   683             else:
   634         A function to perform the value type casting in the set operation  
   684                 value = data_obj.value
   635         """
   685             result.append(value)
   636         
   686         result = utils.distinct_array(result)
   637         if isinstance(value, list):
   687         
   638             value = " ".join(['"%s"' % elem for elem in value])
   688         # Handle None in the result (data element with no text data)
   639         return value
   689         if None in result:
   640     
   690             # If the empty string is a valid option, change the None to that,
   641     def set_value(self, value):
   691             # otherwise ignore
   642         if not isinstance(value, types.ListType):
   692             index = result.index(None)
   643             raise ValueError("Only list types are allowed.")
   693             if '' in self.get_valueset():   result[index] = ''
   644         self.value = value
   694             else:                           del result[index]
       
   695         
       
   696         return tuple(result)
       
   697     
       
   698     def convert_value_to_data(self, value, attr=None):
       
   699         if not isinstance(value, (types.ListType, types.TupleType, types.NoneType)):
       
   700             raise ValueError("Only list, tuple and None types are allowed.")
       
   701         
       
   702         if value:   return [api.Data(fqr=self.fqr, value=v, attr=attr) for v in value]
       
   703         else:       return [api.Data(fqr=self.fqr, empty=True, attr=attr)]
   645 
   704 
   646 class ConfmlDateSetting(ConfmlSetting):
   705 class ConfmlDateSetting(ConfmlSetting):
   647     """
   706     """
   648     Confml setting class for date type.
   707     Confml setting class for date type.
   649     """
   708     """
   665     """
   724     """
   666     def __init__(self, ref,**kwargs):
   725     def __init__(self, ref,**kwargs):
   667         kwargs['type'] = 'dateTime'
   726         kwargs['type'] = 'dateTime'
   668         ConfmlSetting.__init__(self,ref,**kwargs)
   727         ConfmlSetting.__init__(self,ref,**kwargs)
   669 
   728 
       
   729 class ConfmlHexBinarySetting(ConfmlSetting):
       
   730     """
       
   731     Confml setting class for hex-binary type.
       
   732     """
       
   733     def __init__(self, ref,**kwargs):
       
   734         kwargs['type'] = 'hexBinary'
       
   735         ConfmlSetting.__init__(self,ref,**kwargs)
       
   736     
       
   737     def get_valueset(self):
       
   738         return api.ValueRe(r'^([0123456789ABCDEF]{2})*$')
       
   739 
       
   740     def get_data_cast(self, value):
       
   741         value = value or '' # Handle None
       
   742         if value not in self.get_valueset():
       
   743             raise ValueError("Cannot convert value %r of setting '%s' into binary data: Not a valid hex string", value)
       
   744         
       
   745         temp = []
       
   746         for i in xrange(len(value) / 2):
       
   747             start = i * 2
       
   748             end   = start + 2 
       
   749             temp.append(chr(int(value[start:end], 16)))
       
   750         return ''.join(temp)
       
   751     
       
   752     def set_data_cast(self, value):
       
   753         return ''.join(['%02X' % ord(c) for c in value])
       
   754 
   670 class ConfmlDurationSetting(ConfmlSetting):
   755 class ConfmlDurationSetting(ConfmlSetting):
   671     """
   756     """
   672     Confml setting class for date type.
   757     Confml setting class for date type.
   673     """
   758     """
   674     def __init__(self, ref,**kwargs):
   759     def __init__(self, ref,**kwargs):
   709         self.add_feature(ConfmlLocalPath())
   794         self.add_feature(ConfmlLocalPath())
   710         self.add_feature(ConfmlTargetPath())
   795         self.add_feature(ConfmlTargetPath())
   711 
   796 
   712 class ConfmlLocalPath(ConfmlElement, api.Feature):
   797 class ConfmlLocalPath(ConfmlElement, api.Feature):
   713     """
   798     """
   714     Confml file class. Attribute setting.
   799     Confml file class. Attribute setting. 
       
   800     The localPath "name" is always the same as its ref 'localPath'
   715     """
   801     """
   716     def __init__(self, ref='localPath', **kwargs):
   802     def __init__(self, ref='localPath', **kwargs):
   717         kwargs['type'] = 'string'
   803         kwargs['type'] = 'string'
       
   804         kwargs['name'] = ref
   718         ConfmlElement.__init__(self, **kwargs)
   805         ConfmlElement.__init__(self, **kwargs)
   719         api.Feature.__init__(self, ref, **kwargs)
   806         api.Feature.__init__(self, ref, **kwargs)
   720         self.readOnly = kwargs.get('readOnly', None)
   807         self.readOnly = kwargs.get('readOnly', None)
   721 
   808 
   722 
   809 
   723 class ConfmlTargetPath(ConfmlElement, api.Feature):
   810 class ConfmlTargetPath(ConfmlElement, api.Feature):
   724     """
   811     """
   725     Confml file class. Attribute setting.
   812     Confml file class. Attribute setting.
       
   813     The targetPath "name" is always the same as its ref 'targetPath'
   726     """
   814     """
   727     def __init__(self, ref='targetPath', **kwargs):
   815     def __init__(self, ref='targetPath', **kwargs):
   728         kwargs['type'] = 'string'
   816         kwargs['type'] = 'string'
       
   817         kwargs['name'] = ref
   729         ConfmlElement.__init__(self, **kwargs)
   818         ConfmlElement.__init__(self, **kwargs)
   730         api.Feature.__init__(self, ref, **kwargs)
   819         api.Feature.__init__(self, ref, **kwargs)
   731         self.readOnly = kwargs.get('readOnly', None)
   820         self.readOnly = kwargs.get('readOnly', None)
   732 
   821 
       
   822 
       
   823 class ConfmlFeatureLink(ConfmlSettingAttributes, api.FeatureLink):
       
   824     """
       
   825     ConfmlFeatureLink object is the setting reference object inside confml 
       
   826     group / view. It can populate the actual FeatureProxy objects under the
       
   827     particular group / view object.
       
   828     """
       
   829 
       
   830     """ the override_attributes explicitly states which feature link attributes can be overridden """
       
   831     override_attributes = ['name', 
       
   832                            'desc', 
       
   833                            'minLength',
       
   834                            'maxLength',
       
   835                            'minOccurs',
       
   836                            'maxOccurs',
       
   837                            'minInclusive',
       
   838                            'maxInclusive',
       
   839                            'minExclusive',
       
   840                            'maxExclusive',
       
   841                            'pattern',
       
   842                            'totalDigits',
       
   843                            'options',
       
   844                            'properties',
       
   845                            'readOnly'
       
   846                            ]
       
   847     def __init__(self, ref,**kwargs):
       
   848         ConfmlSettingAttributes.__init__(self, ref,**kwargs)
       
   849         api.FeatureLink.__init__(self, ref, **kwargs)
       
   850         self.type = kwargs.get('type',None)
   733 
   851 
   734 class ConfmlMeta(api.Base):
   852 class ConfmlMeta(api.Base):
   735     """
   853     """
   736     Confml meta element
   854     Confml meta element
   737     """
   855     """
   749         del self.array[key]
   867         del self.array[key]
   750 
   868 
   751     def __setitem__(self, key, value):
   869     def __setitem__(self, key, value):
   752         self.array[key] = value
   870         self.array[key] = value
   753 
   871 
       
   872     def __len__(self):
       
   873         return len(self.array)
       
   874     
   754     def __str__(self):
   875     def __str__(self):
   755         tempstr = "ConfmlMeta object\n"
   876         tempstr = "ConfmlMeta object\n"
   756         counter = 0
   877         counter = 0
   757         for item in self.array:
   878         for item in self.array:
   758             tempstr += "\t%d: %s\n" % (counter, item.__str__())
   879             tempstr += "\t%d: %s\n" % (counter, item.__str__())
   788         return default
   909         return default
   789 
   910 
   790     def replace(self, index, tag, value, ns=None, dict=None):
   911     def replace(self, index, tag, value, ns=None, dict=None):
   791         self.array[index] = ConfmlMetaProperty(tag, value, ns, attrs=dict)
   912         self.array[index] = ConfmlMetaProperty(tag, value, ns, attrs=dict)
   792 
   913 
       
   914     def update(self, data):
       
   915         """
       
   916         Update this the ConfmlMeta object meta with the given data.
       
   917         @param data: The input ConfmlMeta data to update for this object
       
   918         """
       
   919         if data:
       
   920             for property in data.array:
       
   921                 self.set_property_by_tag(property.tag, property.value, property.ns, property.attrs)
       
   922 
       
   923 
   793     def clear(self, value):
   924     def clear(self, value):
   794         self.array = []
   925         self.array = []
   795 
   926 
   796     def clone(self):
   927     def clone(self):
   797         newMeta = ConfmlMeta()
   928         newMeta = ConfmlMeta()
   805             if item.tag == value:
   936             if item.tag == value:
   806                 return self.array.index(item)
   937                 return self.array.index(item)
   807         return -1
   938         return -1
   808 
   939 
   809     def find_by_attribute(self, name, value):
   940     def find_by_attribute(self, name, value):
   810         for item in self.array:
   941         for item in self.array:            
   811             if item.attrs.has_key(name) and item.attrs[name] == value: 
   942             if item.attrs.has_key(name) and item.attrs[name] == value:
   812                 return self.array.index(item)
   943                 return self.array.index(item)
   813         return -1
   944         return -1
   814 
   945 
   815     def get_property_by_tag(self, tag):
   946     def get_property_by_tag(self, tag, attrs={}):
   816         """
   947         """
   817         Try to find the element by its tag in the meta elem array.
   948         Try to find the element by its tag in the meta elem array.
   818         @param tag: the tag that is searched
   949         @param tag: the tag that is searched
   819         @return: the ConfmlMetaProperty object if it is found. None if element with tag is not found.
   950         @return: the ConfmlMetaProperty object if it is found. None if element with tag is not found.
   820         """
   951         """ 
   821         for item in self.array:
   952         for item in self.array:
   822             if item.tag == tag:
   953             if item.tag == tag:
   823                 return item
   954                 if not item.attrs or (item.attrs.get("name", None) == attrs.get("name", None)):
       
   955                     return item
   824         return None
   956         return None
   825 
   957 
       
   958     def set_property_by_tag(self, tag, value, ns=None, attributes=None):
       
   959         """
       
   960         Try to find the element by its tag and set it the meta elem array. 
       
   961         This will either create a new element to the meta or replace first 
       
   962         encountered elem in array. 
       
   963         @param tag: the tag that is searched
       
   964         @return: the ConfmlMetaProperty object if it is found. None if element with tag is not found.
       
   965         """
       
   966                 
       
   967         if self.get_property_by_tag(tag, attributes):
       
   968             property = self.get_property_by_tag(tag, attributes) 
       
   969             property.value = value
       
   970             property.attrs = attributes or {}
       
   971         else:
       
   972             self.add(tag, value, ns, attributes)
   826 
   973 
   827 class ConfmlDescription(api.Base):
   974 class ConfmlDescription(api.Base):
   828     """
   975     """
   829     Confml description element
   976     Confml description element
   830     """
   977     """
   842     def __init__(self, href='', **kwargs):
   989     def __init__(self, href='', **kwargs):
   843         super(ConfmlIcon,self).__init__(self.refname)
   990         super(ConfmlIcon,self).__init__(self.refname)
   844         self.href = href
   991         self.href = href
   845 
   992 
   846 
   993 
   847 class ConfmlProperty(api.Base):
       
   848     """
       
   849     Confml meta element
       
   850     """
       
   851     refname = "_property"
       
   852     def __init__(self, **kwargs):
       
   853         """
       
   854         @param name=str: name string 
       
   855         @param value=str: value for the property, string 
       
   856         @param unit=str: unit of the property
       
   857         """
       
   858         super(ConfmlProperty,self).__init__(self.refname)
       
   859         self.name = kwargs.get('name',None)
       
   860         self.value = kwargs.get('value',None)
       
   861         self.unit = kwargs.get('unit',None)
       
   862 
   994 
   863 
   995 
   864 class ConfmlMetaProperty(api.Base):
   996 class ConfmlMetaProperty(api.Base):
   865     """
   997     """
   866     Confml meta property element
   998     Confml meta property element
   871         """
  1003         """
   872         super(ConfmlMetaProperty,self).__init__(self.refname)
  1004         super(ConfmlMetaProperty,self).__init__(self.refname)
   873         self.tag = tag
  1005         self.tag = tag
   874         self.value = value
  1006         self.value = value
   875         self.ns = ns
  1007         self.ns = ns
   876         if kwargs.has_key("attrs") and kwargs["attrs"] != None:
  1008         self.attrs = dict(kwargs.get('attrs') or {})
   877             self.attrs = dict(kwargs["attrs"])
       
   878         else:
       
   879             self.attrs = {}
       
   880 
  1009 
   881     def __cmp__(self, other):
  1010     def __cmp__(self, other):
   882         try:
  1011         try:
   883             if self.tag != other.tag or self.value != other.value\
  1012             if self.tag != other.tag or self.value != other.value\
   884                 or self.ns != other.ns or self.attrs != other.attrs:
  1013                 or self.ns != other.ns or self.attrs != other.attrs:
   888         return 0
  1017         return 0
   889 
  1018 
   890     def __str__(self):
  1019     def __str__(self):
   891         return "Tag: %s Value: %s Namespace: %s Attributes: % s" % (self.tag, self.value, self.ns, repr(self.attrs))         
  1020         return "Tag: %s Value: %s Namespace: %s Attributes: % s" % (self.tag, self.value, self.ns, repr(self.attrs))         
   892         
  1021         
   893             
  1022 
   894 
  1023 class ConfmlNumericValue(api.Base):
   895 class ConfmlLength(api.Base):
  1024     """
       
  1025     Confml base class for all float type properties.
       
  1026     Performs a simple value casting from string to int in value setting.
       
  1027     """
       
  1028     def __init__(self, ref="", **kwargs):
       
  1029         super(ConfmlNumericValue,self).__init__(ref, **kwargs)
       
  1030         self._value = None
       
  1031         
       
  1032     def get_value(self): return self._value
       
  1033     def del_value(self): self._value = None
       
  1034     def set_value(self, value): 
       
  1035         if utils.is_float(value):
       
  1036             self._value = float(value) 
       
  1037         else:
       
  1038             self._value = int(value)
       
  1039     """ The value as a property """
       
  1040     value = property(get_value,set_value,del_value)
       
  1041 
       
  1042 
       
  1043 class ConfmlLength(ConfmlNumericValue):
   896     """
  1044     """
   897     Confml length element
  1045     Confml length element
   898     """
  1046     """
   899     refname = "_length"
  1047     refname = "_length"
   900     def __init__(self, value, **kwargs):
  1048     def __init__(self, value, **kwargs):
   901         super(ConfmlLength,self).__init__(self.refname)
  1049         super(ConfmlLength,self).__init__(self.refname)
   902         self.value = value
  1050         self.value = value
   903 
  1051 
   904 class ConfmlMaxLength(api.Base):
  1052 class ConfmlMaxLength(ConfmlNumericValue):
   905     """
  1053     """
   906     Confml max element
  1054     Confml max element
   907     """
  1055     """
   908     refname = "_maxLength"
  1056     refname = "_maxLength"
   909     def __init__(self, value, **kwargs):
  1057     def __init__(self, value, **kwargs):
   910         super(ConfmlMaxLength,self).__init__(self.refname)
  1058         super(ConfmlMaxLength,self).__init__(self.refname)
   911         self.value = value
  1059         self.value = value
   912 
  1060 
   913 class ConfmlMinLength(api.Base):
  1061 class ConfmlMinLength(ConfmlNumericValue):
   914     """
  1062     """
   915     Confml min element
  1063     Confml min element
   916     """
  1064     """
   917     refname = "_minLength"
  1065     refname = "_minLength"
   918     def __init__(self, value, **kwargs):
  1066     def __init__(self, value, **kwargs):
   919         super(ConfmlMinLength,self).__init__(self.refname)
  1067         super(ConfmlMinLength,self).__init__(self.refname)
   920         self.value = value
  1068         self.value = value
   921 
  1069 
   922 class ConfmlMinInclusive(api.Base):
  1070 class ConfmlMinInclusive(ConfmlNumericValue):
   923     """
  1071     """
   924     Confml minInclusive element
  1072     Confml minInclusive element
   925     """
  1073     """
   926     refname = "_minInclusive"
  1074     refname = "_minInclusive"
   927     def __init__(self, value, **kwargs):
  1075     def __init__(self, value, **kwargs):
   928         super(ConfmlMinInclusive,self).__init__(self.refname)
  1076         super(ConfmlMinInclusive,self).__init__(self.refname)
   929         self.value = value
  1077         self.value = value
   930 
  1078 
   931 class ConfmlMaxInclusive(api.Base):
  1079 class ConfmlMaxInclusive(ConfmlNumericValue):
   932     """
  1080     """
   933     Confml minInclusive element
  1081     Confml minInclusive element
   934     """
  1082     """
   935     refname = "_maxInclusive"
  1083     refname = "_maxInclusive"
   936     def __init__(self, value, **kwargs):
  1084     def __init__(self, value, **kwargs):
   937         super(ConfmlMaxInclusive,self).__init__(self.refname)
  1085         super(ConfmlMaxInclusive,self).__init__(self.refname)
   938         self.value = value
  1086         self.value = value
   939 
  1087 
   940 class ConfmlMinExclusive(api.Base):
  1088 class ConfmlMinExclusive(ConfmlNumericValue):
   941     """
  1089     """
   942     Confml minExclusive element
  1090     Confml minExclusive element
   943     """
  1091     """
   944     refname = "_minExclusive"
  1092     refname = "_minExclusive"
   945     def __init__(self, value, **kwargs):
  1093     def __init__(self, value, **kwargs):
   946         super(ConfmlMinExclusive,self).__init__(self.refname)
  1094         super(ConfmlMinExclusive,self).__init__(self.refname)
   947         self.value = value
  1095         self.value = value
   948 
  1096 
   949 class ConfmlMaxExclusive(api.Base):
  1097 class ConfmlMaxExclusive(ConfmlNumericValue):
   950     """
  1098     """
   951     Confml maxExclusive element
  1099     Confml maxExclusive element
   952     """
  1100     """
   953     refname = "_maxExclusive"
  1101     refname = "_maxExclusive"
   954     def __init__(self, value, **kwargs):
  1102     def __init__(self, value, **kwargs):
   962     refname = "_pattern"
  1110     refname = "_pattern"
   963     def __init__(self, value, **kwargs):
  1111     def __init__(self, value, **kwargs):
   964         super(ConfmlPattern,self).__init__(self.refname)
  1112         super(ConfmlPattern,self).__init__(self.refname)
   965         self.value = value   
  1113         self.value = value   
   966 
  1114 
   967 class ConfmlTotalDigits(api.Base):
  1115 class ConfmlTotalDigits(ConfmlNumericValue):
   968     """
  1116     """
   969     Confml totalDigits element
  1117     Confml totalDigits element
   970     """
  1118     """
   971     refname = "_totalDigits"
  1119     refname = "_totalDigits"
   972     def __init__(self, value, **kwargs):
  1120     def __init__(self, value, **kwargs):