Package ndg :: Package xacml :: Package parsers :: Package etree :: Module attributevaluereader
[hide private]

Source Code for Module ndg.xacml.parsers.etree.attributevaluereader

  1  """NDG XACML ElementTree based reader for AttributeValue type 
  2   
  3  NERC DataGrid 
  4  """ 
  5  __author__ = "P J Kershaw" 
  6  __date__ = "16/03/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: attributevaluereader.py 7955 2011-12-21 18:29:45Z rwilkinson $" 
 12  from ndg.xacml.core.attributevalue import (AttributeValue,  
 13                                             AttributeValueClassFactory) 
 14  from ndg.xacml.parsers import XMLParseError 
 15  from ndg.xacml.parsers.etree import QName 
 16  from ndg.xacml.parsers.etree.expressionreader import ExpressionReader 
 17  from ndg.xacml.utils import VettedDict 
18 19 20 -class AttributeValueReader(ExpressionReader):
21 '''ElementTree based XACML AttributeValue type parser 22 23 @cvar TYPE: XACML class type that this reader will read values into 24 @type TYPE: abc.ABCMeta 25 26 @cvar FACTORY: factory function for returning an Attribute value type for a 27 given XACML Attribute value URI 28 @type FACTORY: ndg.xacml.core.attributevalue.AttributeValueClassFactory 29 ''' 30 TYPE = AttributeValue 31 FACTORY = AttributeValueClassFactory() 32
33 - def __call__(self, obj, common):
34 """Parse *AttributeValue type element - override this method instead of 35 _parseExtension since AttributeValue class is virtual. A sub-type can 36 be instantiated only once the data type attribute is parsed 37 38 @param obj: input object to parse 39 @type obj: ElementTree Element, or stream object 40 @return: new XACML attribute value instance 41 @rtype: ndg.xacml.core.attributevalue.AttributeValue derived type 42 @raise XMLParseError: error reading element 43 """ 44 elem = super(AttributeValueReader, self)._parse(obj) 45 46 xacmlType = self.__class__.TYPE 47 localName = QName.getLocalPart(elem.tag) 48 if localName != xacmlType.ELEMENT_LOCAL_NAME: 49 raise XMLParseError("No \"%s\" element found" % 50 xacmlType.ELEMENT_LOCAL_NAME) 51 52 # Unpack *required* attributes from top-level element 53 elemAttributeValues = [] 54 for attributeName in (xacmlType.DATA_TYPE_ATTRIB_NAME,): 55 attributeValue = elem.attrib.get(attributeName) 56 if attributeValue is None: 57 raise XMLParseError('No "%s" attribute found in "%s" element' % 58 (attributeName, 59 xacmlType.ELEMENT_LOCAL_NAME)) 60 61 elemAttributeValues.append(attributeValue) 62 63 attributeValueClass = self.__class__.FACTORY(elemAttributeValues[0]) 64 if attributeValueClass is None: 65 raise XMLParseError("No Attribute Value class available for " 66 "parsing %r type" % elemAttributeValues[0]) 67 68 attributeValue = attributeValueClass() 69 attributeValue.dataType = elemAttributeValues[0] 70 self._parseExtension(elem, attributeValue) 71 72 return attributeValue
73
74 - def _parseExtension(self, elem, attributeValue):
75 """Parse XML Attribute value element 76 77 @param elem: ElementTree XML element 78 @type elem: xml.etree.Element 79 80 @param attributeValue: attribute selector to be updated with parsed 81 values 82 @type attributeValue: ndg.xacml.core.attributevalue.AttributeValue 83 84 @raise XMLParseError: error parsing attribute ID XML attribute 85 """ 86 reader = DataTypeReaderClassFactory.getReader(attributeValue) 87 reader.parse(elem, attributeValue)
88
89 90 -class ETreeDataTypeReaderBase(object):
91 @classmethod
92 - def parse(cls, elem, attributeValue):
93 if elem.text is None: 94 raise XMLParseError('No attribute value element found parsing %r' % 95 AttributeValueReader.TYPE.ELEMENT_LOCAL_NAME) 96 97 attributeValue.value = elem.text
98
99 100 -class ETreeDataTypeReaderClassMap(VettedDict):
101 """Specialised dictionary to hold mappings of XACML AttributeValue DataTypes 102 and their equivalent ElementTree reader classes 103 """ 104
105 - def __init__(self):
106 """Force entries to derive from AttributeValue and IDs to 107 be string type 108 """ 109 # Filters are defined as staticmethods but reference via self here to 110 # enable derived class to override them as standard methods without 111 # needing to redefine this __init__ method 112 VettedDict.__init__(self, self.keyFilter, self.valueFilter)
113 114 @staticmethod
115 - def keyFilter(key):
116 """Enforce string type keys for Attribute Value DataType URIs 117 118 @param key: URN for attribute 119 @type key: basestring 120 @return: boolean True indicating key is OK 121 @rtype: bool 122 @raise TypeError: incorrect input type 123 """ 124 if not isinstance(key, basestring): 125 raise TypeError('Expecting %r derived type for key; got %r' % 126 (basestring, type(key))) 127 return True
128 129 @staticmethod
130 - def valueFilter(value):
131 """Enforce ElementTree abstract reader derived types for values 132 @param value: attribute value 133 @type value: 134 ndg.xacml.parsers.etree.attributevaluereader.ETreeDataTypeReaderBase to 135 their derived type 136 @return: boolean True indicating attribute value is correct type 137 @rtype: bool 138 @raise TypeError: incorrect input type 139 """ 140 if not issubclass(value, ETreeDataTypeReaderBase): 141 raise TypeError('Expecting %r derived type for value; got %r' % 142 (ETreeDataTypeReaderBase, type(value))) 143 return True
144
145 146 -class DataTypeReaderClassFactory(object):
147 """Return class to parse the content of the Attribute value based on the 148 DataType setting""" 149 MAP = ETreeDataTypeReaderClassMap() 150 _id = None 151 for _id in AttributeValue.TYPE_URIS: 152 MAP[_id] = ETreeDataTypeReaderBase 153 154 del _id 155 156 @classmethod
157 - def addReader(cls, identifier, readerClass):
158 cls.MAP[identifier] = readerClass
159 160 @classmethod
161 - def getReader(cls, attributeValue):
162 return cls.MAP[attributeValue.dataType]
163