Added LICENSE
[nepi.git] / src / nepi / execution / attribute.py
1 """
2     NEPI, a framework to manage network experiments
3     Copyright (C) 2013 INRIA
4
5     This program is free software: you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation, either version 3 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18 """
19
20 ### Attribute Types
21 class Types:
22     String  = "STRING"
23     Bool    = "BOOL"
24     Enum    = "ENUM"
25     Double  = "DOUBLE"
26     Integer = "INTEGER"
27
28 ### Attribute Flags
29 class Flags:
30     # Attribute can be modified by the user 
31     NoFlags         = 0x00
32     # Attribute is not modifiable by the user
33     ReadOnly        = 0x01
34     # Attribute is not modifiable by the user during runtime
35     ExecReadOnly        = 0x02
36     # Attribute is an access credential
37     Credential      = 0x04
38
39 class Attribute(object):
40     def __init__(self, name, help, type = Types.String,
41             flags = Flags.NoFlags, default = None, allowed = None,
42             set_hook = None):
43         self._name = name
44         self._help = help
45         self._type = type
46         self._flags = flags
47         self._allowed = allowed
48         self._default = self._value = default
49         # callback to be invoked upon changing the 
50         # attribute value
51         self.set_hook = set_hook
52
53     @property
54     def name(self):
55         return self._name
56
57     @property
58     def default(self):
59         return self._default
60
61     @property
62     def type(self):
63         return self._type
64
65     @property
66     def help(self):
67         return self._help
68
69     @property
70     def flags(self):
71         return self._flags
72
73     @property
74     def allowed(self):
75         return self._allowed
76
77     def has_flag(self, flag):
78         return (self._flags & flag) == flag
79
80     def get_value(self):
81         return self._value
82
83     def set_value(self, value):
84         valid = True
85
86         if self.type == Types.Enum:
87             valid = value in self._allowed
88         
89         valid = valid and self.is_valid_value(value)
90
91         if valid: 
92             if self.set_hook:
93                 # Hook receives old value, new value
94                 value = self.set_hook(self._value, value)
95
96             self._value = value
97         else:
98             raise ValueError("Invalid value %s for attribute %s" %
99                     (str(value), self.name))
100
101     value = property(get_value, set_value)
102
103     def is_valid_value(self, value):
104         """ Attribute subclasses will override this method to add 
105         adequate validation"""
106         return True
107