source: TI12-security/trunk/python/Tests/etreewss/client/elementtreeproxy.py @ 4024

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/Tests/etreewss/client/elementtreeproxy.py@4024
Revision 4024, 7.0 KB checked in by pjkersha, 12 years ago (diff)

Integration of ElementTree with C14N into ZSI's ElementProxy? interface class.

Line 
1'''ZSI ElementTree ElementProxy class an interface to ZSI's ElementProxy
2
3Freely adapted from original by Joshua R. Boverhof, LBNL
4'''
5from ZSI.wstools.Namespaces import SCHEMA, XMLNS, SOAP
6from ZSI.wstools.Utility import MessageInterface
7from elementtree import ElementC14N, ElementTree
8from StringIO import StringIO
9
10
11class ElementProxyException(Exception):
12    ''''''
13
14class ElementTreeProxy(MessageInterface):
15    '''ElementTree wrapper
16    TODO: issue with "getPrefix"
17    '''
18    _soap_env_prefix = 'SOAP-ENV'
19    _soap_enc_prefix = 'SOAP-ENC'
20    _soap_env_nsuri = SOAP.ENV
21    _soap_enc_nsuri = SOAP.ENC
22
23    def __init__(self, sw, message=None):
24        '''Initialize.
25           sw -- SoapWriter
26        '''
27        assert message is None, 'TODO'
28        self._etree = None
29
30    def __str__(self):
31        return self.toString()
32       
33    def toString(self):
34        return ElementTree.tostring(self._etree)
35
36    #############################################
37    #Methods used in TypeCodes
38    #############################################
39    def createAppendElement(self, namespaceURI, localName, prefix=None):
40        '''Create a new element (namespaceURI,name), append it
41           to current node, and return the newly created node.
42        Keyword arguments:
43            namespaceURI -- namespace of element to create
44            localName -- local name of new element
45            prefix -- if namespaceURI is not defined, declare prefix.  defaults
46                to 'ns1' if left unspecified.
47        '''
48        if not prefix:
49            prefix = 'ns0'
50           
51        if namespaceURI: 
52                     
53            # Search for matching prefix
54            matchingPrefix = None
55            for elem in self._etree.getiterator():
56                for k, v in elem.items():
57                    if k.startswith("xmlns:") and v == namespaceURI:
58                        # Namespace declaration found
59                        matchingPrefix = k[6:]
60                        break
61
62            elem = ElementTree.Element("{%s}%s" % (namespaceURI, localName))
63
64            if not matchingPrefix:
65                matchingPrefix = prefix
66
67            self._etree.set("xmlns:%s" % matchingPrefix, namespaceURI)               
68        else:
69            assert prefix, "Prefix must be set - no namespaceURI was provided"
70            print 'HELLO'
71            # Search for matching NS
72            for elem in self._etree.getiterator():
73                for k, v in elem.items():
74                    if k.startswith("xmlns:") and k[6:] == prefix:
75                        namespaceURI  = v
76                        break
77                   
78            elem = ElementTree.Element("{%s}%s:%s" % (namespaceURI, 
79                                                     prefix,
80                                                     localName))
81       
82           
83        self._etree.append(elem)
84       
85        eproxy = ElementTreeProxy(None)
86        eproxy._etree = elem
87
88        return eproxy
89
90    def createAppendTextNode(self, pyobj):
91        '''TODO: obviously mixed text content cannot be accurately
92        represented via this interface.  Only 1 possible text node/element
93        '''
94        self._etree.text = pyobj
95
96    def createDocument(self, namespaceURI=SOAP.ENV, localName='Envelope'):
97
98        prefix = self._soap_env_prefix
99
100        self._etree = ElementTree.Element('{%s}%s' %(namespaceURI, localName))
101        self._etree.set("xmlns:%s" % prefix, namespaceURI)
102       
103    def getElement(self, namespaceURI, localName):
104        for e in self._etree.getchildren():
105            l = e.tag.strip('{').split('}')
106            if not namespaceURI:
107                if len(l) == 1 and l[0] == localName:
108                    eproxy = ElementTreeProxy(None)
109                    eproxy._etree = e
110                    return eproxy
111            elif len(l) == 2 and l[0] == namespaceURI and l[1] == localName:
112                eproxy = ElementTreeProxy(None)
113                eproxy._etree = e
114                return eproxy
115               
116        raise ElementProxyException,\
117            'No such element(%s,%s)' %(namespaceURI,localName)
118       
119    def getPrefix(self, namespaceURI):
120        '''TODO: this is not possible w/elementTree since namespace prefix
121        mappings aren't done until serialization.  completely abstraced out.
122        '''
123        raise NotImplementedError, 'this func isnt going to work'
124       
125    def setAttributeNS(self, namespaceURI, localName, value):
126        '''
127        Keyword arguments:
128            namespaceURI -- namespace of attribute to create, None is for
129                attributes in no namespace.
130            localName -- local name of new attribute
131            value -- value of new attribute
132        ''' 
133        self._etree.attrib["{%s}%s" %(namespaceURI, localName)] = value
134       
135    def setAttributeType(self, namespaceURI, localName):
136        '''xsi:type attribute, value must be a QName
137        '''
138        self.setAttributeNS(SCHEMA.XSI3, 'type', 
139            ElementTree.QName('{%s}%s' %(namespaceURI,localName))
140        )
141       
142    def setNamespaceAttribute(self, prefix, namespaceURI):
143        '''TODO: Not sure how to force this to be used by ElementTree
144        Keyword arguments:
145            prefix -- xmlns prefix
146            namespaceURI -- value of prefix
147        '''
148        #self._etree.attrib["xmlns:%s" %prefix] = namespaceURI
149        self._etree.set("xmlns:%s" % prefix, namespaceURI)
150       
151    def canonicalize(self, **kw):
152        # Make copy as this is a destructive process - attributes get deleted!
153#        etree = self._etree.copy()
154#        root = ElementTree.ElementTree(etree)
155#   
156#        root._scope = {}
157#        root._parent=dict((c, p) for p in etree.getiterator() for c in p)
158#   
159#        # build scope map
160#        for e in self._etree.getiterator():
161#            scope = []
162#            for k in e.keys():
163#                if k.startswith("xmlns:"):
164#                    # move xmlns prefix to scope map
165#                    scope.append((k[6:], e.get(k)))
166#                    del e.attrib[k]
167#            if scope:
168#                root._scope[e] = scope
169#   
170#        # Save as C14N
171#        f = StringIO()
172#        ElementC14N.write(root, f, **kw)
173#        c14n = f.getvalue()
174#        return c14n
175        root = ElementTree.ElementTree(self._etree)
176   
177        root._scope = {}
178        root._parent=dict((c, p) for p in self._etree.getiterator() for c in p)
179   
180        # build scope map
181        for e in self._etree.getiterator():
182            scope = []
183            for k in e.keys():
184                if k.startswith("xmlns:"):
185                    # move xmlns prefix to scope map
186                    scope.append((k[6:], e.get(k)))
187                    del e.attrib[k]
188            if scope:
189                root._scope[e] = scope
190   
191        # Save as C14N
192        f = StringIO()
193        ElementC14N.write(root, f, **kw)
194        c14n = f.getvalue()
195        return c14n
196   
197    def evaluate(self, expression, processorNss=None):
198        return self._etree.findall(expression, namespaces=processorNss)
Note: See TracBrowser for help on using the repository browser.