netns module can build description factories
[nepi.git] / src / nepi / core / attributes.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 class AttributesMap(object):
5     """AttributesMap is the base class for every object whose attributes 
6     are going to be manipulated by the end-user in a script or GUI.
7     """
8     def __init__(self):
9         self._attributes = dict()
10
11     @property
12     def attributes_name(self):
13         return set(self._attributes.keys())
14
15     def set_attribute_value(self, name, value):
16         self._attributes[name].value = value
17
18     def set_attribute_readonly(self, name, value):
19         self._attributes[name].readonly = value
20
21     def get_attribute_value(self, name):
22         return self._attributes[name].value
23
24     def get_attribute_help(self, name):
25         return self._attributes[name].help
26
27     def get_attribute_type(self, name):
28         return self._attributes[name].type
29
30     def get_attribute_range(self, name):
31         return self._attributes[name].range
32
33     def get_attribute_allowed(self, name):
34         return self._attributes[name].allowed
35
36     def get_attribute_readonly(self, name):
37         return self._attributes[name].readonly
38
39     def add_attribute(self, name, help, type, value = None, range = None,
40         allowed = None, readonly = False, validation_function = None):
41         if name in self._attributes:
42             raise AttributeError("Attribute %s already exists" % name)
43         attribute = Attribute(name, help, type, value, range, allowed, readonly,
44                 validation_function)
45         self._attributes[name] = attribute
46
47     def del_attribute(self, name):
48         del self._attributes[name]
49
50     def has_attribute(self, name):
51         return name in self._attributes    
52     
53     def destroy(self):
54         self._attributes = dict()
55
56 class Attribute(object):
57     STRING, BOOL, ENUM, DOUBLE, INTEGER = (
58                 "STRING", "BOOL", "ENUM", "DOUBLE", "INTEGER")
59
60     types = [STRING, BOOL, ENUM, DOUBLE, INTEGER]
61
62     def __init__(self, name, help, type, value = None, range = None,
63         allowed = None, readonly = False, validation_function = None):
64         if not type in Attribute.types:
65             raise AttributeError("invalid type %s " % type)
66         self.name = name
67         self._type = type
68         self._help = help
69         self._value = value
70         self._validation_function = validation_function
71         self._readonly = (readonly == True)
72         self._modified = False
73         # range: max and min possible values
74         self._range = range
75         # list of possible values
76         self._allowed = allowed
77
78     @property
79     def type(self):
80         return self._type
81
82     @property
83     def help(self):
84         return self._help
85
86     @property
87     def readornly(self):
88         return self._readonly
89
90     @property
91     def modified(self):
92         return self._modified
93
94     @property
95     def range(self):
96         return self._range
97
98     @property
99     def allowed(self):
100         return self._allowed
101
102     def get_value(self):
103         return self._value
104
105     def set_value(self, value):
106         if self._is_in_range(value) and \
107                 self._is_in_allowed_values(value) and \
108                 self._is_valid(value):
109             self._value = value
110             self._modified = True
111         else:
112             raise RuntimeError("Invalid value %s for attribute %s" %
113                     (str(value), self.name))
114
115     value = property(get_value, set_value)
116
117     def _is_in_range(self, value):
118         return not self.range or \
119                 (value >= self.range[0] and value <= self.range[1])
120
121     def _is_in_allowed_values(self, value):
122         return not self.allowed or value in self._allowed
123
124     def _is_valid(self, value):
125         return not self._validation_function or self._validation_function(value)
126