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

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

Added AttributeValueFactory? to generate <type>AttributeValue? classes.

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        self.__value = None
47           
48    def _get_value(self):
49        return self.__value
50
51    def _set_value(self, value):
52        if not isinstance(value, self.__class__.TYPE):
53            raise TypeError('Expecting %r type for "value" '
54                            'attribute; got %r' % (self.__class__.TYPE, 
55                                                   type(value)))
56           
57        self.__value = value 
58
59    value = property(_get_value, _set_value, None, "expression value") 
60   
61    def evaluate(self, context):
62        """Evaluate the result of the expression in a condition
63        @param context: the request context
64        @type context: ndg.xacml.core.context.request.Request
65        @return: attribute value(s) resulting from execution of this expression
66        in a condition
67        @rtype: AttributeValue/NoneType 
68        """ 
69        return self.__value
70
71
72class AttributeValueClassMap(VettedDict):
73    """Specialised dictionary to hold mappings of XML attribute type URIs to
74    their equivalent classes
75    """
76   
77    def __init__(self):
78        """Force entries to derive from AttributeValue and IDs to
79        be string type
80        """       
81        # Filters are defined as staticmethods but reference via self here to
82        # enable derived class to override them as standard methods without
83        # needing to redefine this __init__ method           
84        super(AttributeValueClassMap, self).__init__(self.keyFilter, 
85                                                     self.valueFilter)
86       
87    @staticmethod
88    def keyFilter(key):
89        """Enforce string type keys"""
90        if not isinstance(key, basestring):
91            raise TypeError('Expecting %r type for key; got %r' % 
92                            (basestring, type(key))) 
93        return True 
94   
95    @staticmethod
96    def valueFilter(value):
97        """Enforce AttributeValue derived types for values"""
98
99        if not issubclass(value, AttributeValue):
100            raise TypeError('Expecting %r derived type for value; got %r' % 
101                            (AttributeValue, type(value))) 
102        return True 
103
104
105# Dynamically Create classes based on AttributeValue for all the XACML primitive
106# types
107_IDENTIFIER2CLASS_MAP = AttributeValueClassMap()
108
109for typeName, _type in AttributeValue.TYPE_MAP.items():
110    identifier = AttributeValue.IDENTIFIER_PREFIX + typeName[0
111                                                        ].lower() + typeName[1:]
112
113    className = typeName + AttributeValue.CLASS_NAME_SUFFIX               
114    classVars = {'TYPE': _type, 'IDENTIFIER_NS': identifier}
115   
116    attributeValueClass = type(className, (AttributeValue, ), classVars)
117    AttributeValue.register(attributeValueClass)
118    _IDENTIFIER2CLASS_MAP[identifier] = attributeValueClass
119   
120   
121class AttributeValueFactory(object):
122    """Create AttributeValue types based on the XML namespace identifier
123   
124    Convenience wrapper for _IDENTIFIER2CLASS_MAP instance of
125    AttributeValueClassMap
126    """
127    def __init__(self, classMap=None):
128        if classMap is None:
129            self.__classMap = _IDENTIFIER2CLASS_MAP
130        elif isinstance(classMap, AttributeValueClassMap):
131            self.__classMap = classMap
132        else:
133            raise TypeError('Expecting %r derived type for "map" input; got %r'
134                            % (AttributeValueClassMap, type(map)))
135           
136    def __call__(self, identifier):
137        """Return <type>AttributeValue class for given identifier URI or None
138        if no match is found
139        """
140        return self.__classMap.get(identifier)
141       
Note: See TracBrowser for help on using the repository browser.