source: TI12-security/trunk/ndg_xacml/ndg/xacml/utils/__init__.py @ 7109

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/ndg_xacml/ndg/xacml/utils/__init__.py@7109
Revision 7109, 7.9 KB checked in by pjkersha, 10 years ago (diff)

Incomplete - task 2: XACML-Security Integration

  • updating epydoc ready for release.
  • Property svn:keywords set to Id
Line 
1"""Utilities package for NDG XACML
2
3NERC DataGrid
4"""
5__author__ = "P J Kershaw"
6__date__ = "02/04/09"
7__copyright__ = ""
8__license__ = "BSD - see LICENSE file in top-level directory"
9__contact__ = "Philip.Kershaw@stfc.ac.uk"
10__revision__ = '$Id$'
11import UserDict
12
13# Interpret a string as a boolean
14str2Bool = lambda str: str.lower() in ("yes", "true", "t", "1")
15
16class UniqList(list):
17    """Extended version of list type to enable a list with unique items.
18    If an item is added that is already present then it is silently omitted
19    from the list
20    """
21   
22    def extend(self, iter):
23        """Extend a list with input iterable
24        @param iter: iterable object
25        @type iter: iterable type
26        """
27        return super(UniqList, self).extend([i for i in iter if i not in self])
28       
29    def __iadd__(self, iter):
30        """Extend a list with input iterable
31        @param iter: iterable object
32        @type iter: iterable type
33        """
34        return super(UniqList, self).__iadd__([i for i in iter 
35                                               if i not in self])
36         
37    def append(self, item):
38        """Add an item to the list
39        @param item: item to append to list
40        @type item: any
41        """
42        for i in self:
43            if i == item:
44                return None
45           
46        return super(UniqList, self).append(item)
47
48
49class TypedList(list):
50    """Extend list type to enabled only items of a given type.  Supports
51    any type where the array type in the Standard Library is restricted to
52    only limited set of primitive types
53    """
54   
55    def __init__(self, elementType, *arg, **kw):
56        """
57        @type elementType: type/tuple
58        @param elementType: object type or types which the list is allowed to
59        contain.  If more than one type, pass as a tuple
60        """
61        self.__elementType = elementType
62        super(TypedList, self).__init__(*arg, **kw)
63
64    def __repr__(self):
65        """@return: represent instance giving type information about the
66        elements
67        @rtype: string
68        """
69        return "%r type: %s" % (self.__elementType, 
70                                super(TypedList, self).__repr__())
71       
72    def _getElementType(self):
73        """@return: the element type for this list
74        @rtype: type
75        """
76        return self.__elementType
77   
78    elementType = property(fget=_getElementType, 
79                           doc="The allowed type or types for list elements")
80     
81    def extend(self, iter):
82        """Extend a list with input iterable
83        @param iter: iterable object
84        @type iter: iterable type
85        @raise TypeError: input item doesn't match list type
86        """
87        for i in iter:
88            if not isinstance(i, self.__elementType):
89                raise TypeError("List items must be of type %s" % 
90                                (self.__elementType,))
91               
92        return super(TypedList, self).extend(iter)
93       
94    def __iadd__(self, iter):
95        """Extend a list with input iterable
96        @param iter: iterable object
97        @type iter: iterable type
98        @raise TypeError: input item doesn't match list type
99        """
100        for i in iter:
101            if not isinstance(i, self.__elementType):
102                raise TypeError("List items must be of type %s" % 
103                                (self.__elementType,))
104                   
105        return super(TypedList, self).__iadd__(iter)
106         
107    def append(self, item):
108        """Add an item to the list
109        @param iter: iterable object
110        @type iter: iterable type
111        @raise TypeError: input item doesn't match list type
112        """
113        if not isinstance(item, self.__elementType):
114                raise TypeError("List items must be of type %s" % 
115                                (self.__elementType,))
116   
117        return super(TypedList, self).append(item)
118
119
120class RestrictedKeyNamesDict(dict):
121    """Utility class for holding a constrained list of key names
122    """
123   
124    def __init__(self, *arg, **kw):
125        """Alter standard dict() initialisation to fix key names set at
126        initialisation
127        """
128        super(RestrictedKeyNamesDict, self).__init__(*arg, **kw)
129        self.__keyNames = self.keys() 
130         
131    def __setitem__(self, key, val):
132        """@param key: key for item to set
133        @type key: any
134        @param val: value to set for this key
135        @type val: any
136        """
137        if key not in self.__keyNames:
138            raise KeyError('Key name %r not recognised.  Valid key names '
139                           'are: %r' % (key, self.__keyNames))
140           
141        dict.__setitem__(self, key, val)
142
143    def update(self, d, **kw):       
144        """@param d: dictionary to update from
145        @type d: dict
146        @param kw: keywords to update dictionary with
147        @type kw: dict
148        """
149        for dictArg in (d, kw):
150            for k in dictArg:
151                if k not in self.__keyNames:
152                    raise KeyError('Key name "%s" not recognised.  Valid '
153                                   'key names are: %s' % 
154                                   self.__keyNames)
155       
156        dict.update(self, d, **kw)
157       
158
159_isIterable = lambda obj: getattr(obj, '__iter__', False)
160
161 
162class VettedDict(UserDict.DictMixin):
163    """Enforce custom checking on keys and items before addition to a
164    dictionary
165    """
166   
167    def __init__(self, *args):
168        """Initialise setting the allowed type or types for keys and items
169       
170        @param args: two arguments: the first is a callable which filters for
171        permissable keys in this dict, the second sets the type or list of
172        types permissable for items in this dict
173        @type args: tuple
174        """
175        if len(args) != 2:
176            raise TypeError('__init__() takes 2 arguments, KeyFilter and '
177                            'valueFilter (%d given)' % len(args))
178       
179        # Validation of inputs
180        for arg, argName in zip(args, ('KeyFilter', 'valueFilter')):
181            if not callable(arg):
182                raise TypeError('Expecting callable for %r input; got %r' % 
183                                (argName, type(arg)))
184
185        self.__KeyFilter, self.__valueFilter = args
186       
187        self.__map = {}
188       
189    def _verifyKeyValPair(self, key, val):
190        """Check given key value pair and return False if they should be
191        filtered out.  Filter functions may also raise an exception if they
192        wish to abort completely
193       
194        @param key: dict key to check
195        @type key: basestring
196        @param val: value to check
197        @type val: any
198        """
199        if not self.__KeyFilter(key):
200            return False
201       
202        elif not self.__valueFilter(val):
203            return False
204       
205        else:
206            return True
207                 
208    def __setitem__(self, key, val):
209        """Enforce type checking when setting new items
210       
211        @param key: key for item to set
212        @type key: any
213        @param val: value to set for this key
214        @type val: any
215        """       
216        if self._verifyKeyValPair(key, val):
217            self.__map[key] = val
218
219    def __getitem__(self, key):
220        """Provide implementation for getting items
221        @param key: key for item to retrieve
222        @type key: any
223        @return: value for input key
224        @rtype: any
225        """
226        if key not in self.__map:
227            raise KeyError('%r key not found in dict' % key)
228       
229        return self.__map[key]
230   
231    def get(self, key, *arg):
232        """Provide implementation of get item with default
233       
234        @param key: key for item to retrieve
235        @type key: any
236        @param arg: use to set a default argument
237        @type arg: tuple
238        """
239        if key in self.__map:
240            return self.__map[key]
241       
242        elif len(arg) > 1:
243            # Default value set
244            return arg[1]
245        else:
246            return None
247           
248
249   
Note: See TracBrowser for help on using the repository browser.