source: TI12-security/trunk/NDG_XACML/ndg/xacml/core/attributevalue.py @ 6802

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/NDG_XACML/ndg/xacml/core/attributevalue.py@6802
Revision 6802, 5.0 KB checked in by pjkersha, 9 years ago (diff)

Fixed AttributeValueReader? to handler attribute value derived types correctly.

Line 
1"""NDG XACML attribute type definition
2
3NERC DataGrid Project
4"""
5__author__ = "P J Kershaw"
6__date__ = "25/02/10"
7__copyright__ = "(C) 2010 Science and Technology Facilities Council"
8__contact__ = "Philip.Kershaw@stfc.ac.uk"
9__license__ = "BSD - see LICENSE file in top-level directory"
10__contact__ = "Philip.Kershaw@stfc.ac.uk"
11__revision__ = "$Id: $"
12from datetime import datetime, timedelta
13
14from ndg.xacml.utils import VettedDict
15from ndg.xacml.core.expression import Expression
16   
17
18class AttributeValue(Expression):
19    """XACML Attribute Value type"""
20    ELEMENT_LOCAL_NAME = 'AttributeValue'
21    CLASS_NAME_SUFFIX = 'AttributeValue'
22    IDENTIFIER_PREFIX = 'http://www.w3.org/2001/XMLSchema#'
23    IDENTIFIER = None
24    TYPE_MAP = {
25        'String': basestring,
26        'AnyURI': basestring,
27        'Integer': int,
28        'Boolean': bool,
29        'Double': float,
30        'Date': datetime,
31        'DateTime': datetime,
32        'Time': datetime,
33        'DayTimeDuration': timedelta,
34        'YearMonthDuration': timedelta,
35        'X500Name': basestring,
36        'Rfc822Name': basestring,
37        'HexBinary': int,
38        'Base64Binary': NotImplemented
39    }
40    TYPE = None
41   
42    __slots__ = ('__value',) 
43   
44    def __init__(self):
45        super(AttributeValue, self).__init__()
46        if self.__class__.TYPE is None:
47            raise TypeError('TYPE class variable must be set to a valid type '
48                            'in a derived class')
49           
50        self.__value = None
51           
52    def _get_value(self):
53        return self.__value
54
55    def _set_value(self, value):
56        if not isinstance(value, self.__class__.TYPE):
57            raise TypeError('Expecting %r type for "value" '
58                            'attribute; got %r' % (self.__class__.TYPE, 
59                                                   type(value)))
60           
61        self.__value = value 
62
63    value = property(_get_value, _set_value, None, "expression value") 
64   
65    def evaluate(self, context):
66        """Evaluate the result of the expression in a condition
67        @param context: the request context
68        @type context: ndg.xacml.core.context.request.Request
69        @return: attribute value(s) resulting from execution of this expression
70        in a condition
71        @rtype: AttributeValue/NoneType 
72        """ 
73        return self.__value
74
75
76class AttributeValueClassMap(VettedDict):
77    """Specialised dictionary to hold mappings of XML attribute type URIs to
78    their equivalent classes
79    """
80   
81    def __init__(self):
82        """Force entries to derive from AttributeValue and IDs to
83        be string type
84        """       
85        # Filters are defined as staticmethods but reference via self here to
86        # enable derived class to override them as standard methods without
87        # needing to redefine this __init__ method           
88        super(AttributeValueClassMap, self).__init__(self.keyFilter, 
89                                                     self.valueFilter)
90       
91    @staticmethod
92    def keyFilter(key):
93        """Enforce string type keys"""
94        if not isinstance(key, basestring):
95            raise TypeError('Expecting %r type for key; got %r' % 
96                            (basestring, type(key))) 
97        return True 
98   
99    @staticmethod
100    def valueFilter(value):
101        """Enforce AttributeValue derived types for values"""
102
103        if not issubclass(value, AttributeValue):
104            raise TypeError('Expecting %r derived type for value; got %r' % 
105                            (AttributeValue, type(value))) 
106        return True 
107
108
109# Dynamically Create classes based on AttributeValue for all the XACML primitive
110# types
111_IDENTIFIER2CLASS_MAP = AttributeValueClassMap()
112
113for typeName, _type in AttributeValue.TYPE_MAP.items():
114    identifier = AttributeValue.IDENTIFIER_PREFIX + typeName[0
115                                                        ].lower() + typeName[1:]
116
117    className = typeName + AttributeValue.CLASS_NAME_SUFFIX               
118    classVars = {'TYPE': _type, 'IDENTIFIER_NS': identifier}
119   
120    attributeValueClass = type(className, (AttributeValue, ), classVars)
121    AttributeValue.register(attributeValueClass)
122    _IDENTIFIER2CLASS_MAP[identifier] = attributeValueClass
123   
124   
125class AttributeValueClassFactory(object):
126    """Create AttributeValue types based on the XML namespace identifier
127   
128    Convenience wrapper for _IDENTIFIER2CLASS_MAP instance of
129    AttributeValueClassMap
130    """
131    def __init__(self, classMap=None):
132        if classMap is None:
133            self.__classMap = _IDENTIFIER2CLASS_MAP
134        elif isinstance(classMap, AttributeValueClassMap):
135            self.__classMap = classMap
136        else:
137            raise TypeError('Expecting %r derived type for "map" input; got %r'
138                            % (AttributeValueClassMap, type(map)))
139           
140    def __call__(self, identifier):
141        """Return <type>AttributeValue class for given identifier URI or None
142        if no match is found
143        """
144        return self.__classMap.get(identifier)
145       
Note: See TracBrowser for help on using the repository browser.