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

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

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

Line 
1from elementtree import ElementC14N as ET
2from ZSI.wstools.Utility import ElementProxy as _ElementProxy
3
4class ElementProxy(_ElementProxy):
5    '''
6    '''
7
8    def __init__(self, sw, **kw):
9        '''Initialize.
10           sw -- SoapWriter
11        '''
12        _ElementProxy.__init__(self, sw, **kw)
13
14        self._dom = DOM
15        self.node = None
16
17    def __str__(self):
18        return self.toString()
19
20    def evaluate(self, expression, processorNss=None):
21        '''expression -- XPath compiled expression
22        '''
23        nodes = elem.findall(expression, 
24                             namespaces=processorNss or self.processorNss)
25
26        return map(lambda node: ElementProxy(self.sw, node), nodes)
27
28    #############################################
29    # Methods for checking/setting the
30    # classes (namespaceURI,name) node.
31    #############################################
32    def checkNode(self, namespaceURI=None, localName=None):
33        '''
34            namespaceURI -- namespace of element
35            localName -- local name of element
36        '''
37        namespaceURI = namespaceURI or self.namespaceURI
38        localName = localName or self.name
39        check = False
40        if localName and self.node:
41            check = self._dom.isElement(self.node, localName, namespaceURI)
42        if not check:
43            raise NamespaceError, 'unexpected node type %s, expecting %s' %(self.node, localName)
44
45    def setNode(self, node=None):
46        if node:
47            if isinstance(node, ElementProxy):
48                self.node = node._getNode()
49            else:
50                self.node = node
51        elif self.node:
52            node = self._dom.getElement(self.node, self.name, self.namespaceURI, default=None)
53            if not node:
54                raise NamespaceError, 'cant find element (%s,%s)' %(self.namespaceURI,self.name)
55            self.node = node
56        else:
57            #self.node = self._dom.create(self.node, self.name, self.namespaceURI, default=None)
58            self.createDocument(self.namespaceURI, localName=self.name, doctype=None)
59       
60        self.checkNode()
61
62    #############################################
63    # Wrapper Methods for direct DOM Element Node access
64    #############################################
65    def _getNode(self):
66        return self.node
67
68    def _getElements(self):
69        return self._dom.getElements(self.node, name=None)
70
71    def _getOwnerDocument(self):
72        return self.node.ownerDocument or self.node
73
74    def _getUniquePrefix(self):
75        '''I guess we need to resolve all potential prefixes
76        because when the current node is attached it copies the
77        namespaces into the parent node.
78        '''
79        while 1:
80            self._indx += 1
81            prefix = 'ns%d' %self._indx
82            try:
83                self._dom.findNamespaceURI(prefix, self._getNode())
84            except DOMException, ex:
85                break
86        return prefix
87
88    def _getPrefix(self, node, nsuri):
89        '''
90        Keyword arguments:
91            node -- DOM Element Node
92            nsuri -- namespace of attribute value
93        '''
94        try:
95            if node and (node.nodeType == node.ELEMENT_NODE) and \
96                (nsuri == self._dom.findDefaultNS(node)):
97                return None
98        except DOMException, ex:
99            pass
100        if nsuri == XMLNS.XML:
101            return self._xml_prefix
102        if node.nodeType == Node.ELEMENT_NODE:
103            for attr in node.attributes.values():
104                if attr.namespaceURI == XMLNS.BASE \
105                   and nsuri == attr.value:
106                        return attr.localName
107            else:
108                if node.parentNode:
109                    return self._getPrefix(node.parentNode, nsuri)
110        raise NamespaceError, 'namespaceURI "%s" is not defined' %nsuri
111
112    def _appendChild(self, node):
113        '''
114        Keyword arguments:
115            node -- DOM Element Node
116        '''
117        if node is None:
118            raise TypeError, 'node is None'
119        self.node.appendChild(node)
120
121    def _insertBefore(self, newChild, refChild):
122        '''
123        Keyword arguments:
124            child -- DOM Element Node to insert
125            refChild -- DOM Element Node
126        '''
127        self.node.insertBefore(newChild, refChild)
128
129    def _setAttributeNS(self, namespaceURI, qualifiedName, value):
130        '''
131        Keyword arguments:
132            namespaceURI -- namespace of attribute
133            qualifiedName -- qualified name of new attribute value
134            value -- value of attribute
135        '''
136        self.node.setAttributeNS(namespaceURI, qualifiedName, value)
137
138    #############################################
139    #General Methods
140    #############################################
141    def isFault(self):
142        '''check to see if this is a soap:fault message.
143        '''
144        return False
145
146    def getPrefix(self, namespaceURI):
147        try:
148            prefix = self._getPrefix(node=self.node, nsuri=namespaceURI)
149        except NamespaceError, ex:
150            prefix = self._getUniquePrefix() 
151            self.setNamespaceAttribute(prefix, namespaceURI)
152        return prefix
153
154    def getDocument(self):
155        return self._getOwnerDocument()
156
157    def setDocument(self, document):
158        self.node = document
159
160    def importFromString(self, xmlString):
161        doc = self._dom.loadDocument(StringIO(xmlString))
162        node = self._dom.getElement(doc, name=None)
163        clone = self.importNode(node)
164        self._appendChild(clone)
165
166    def importNode(self, node):
167        if isinstance(node, ElementProxy):
168            node = node._getNode()
169        return self._dom.importNode(self._getOwnerDocument(), node, deep=1)
170
171    def loadFromString(self, data):
172        #self.node = self._dom.loadDocument(StringIO(data))
173        self.node = ET.parse(StringIO(data))
174
175    def canonicalize(self, **kw):
176        f = StringIO()
177        ETC14N.write(self.node, f, **kw)
178        c14n = f.getvalue()
179        return c14n
180
181    def toString(self):
182        return self.canonicalize()
183
184    def createDocument(self, namespaceURI, localName, doctype=None):
185        '''If specified must be a SOAP envelope, else may contruct an empty document.
186        '''
187        prefix = self._soap_env_prefix
188
189        if namespaceURI == self.reserved_ns[prefix]:
190            qualifiedName = '%s:%s' %(prefix,localName)
191        elif namespaceURI is localName is None:
192            self.node = self._dom.createDocument(None,None,None)
193            return
194        else:
195            raise KeyError, 'only support creation of document in %s' %self.reserved_ns[prefix]
196
197        document = self._dom.createDocument(nsuri=namespaceURI, qname=qualifiedName, doctype=doctype)
198        self.node = document.childNodes[0]
199
200        #set up reserved namespace attributes
201        for prefix,nsuri in self.reserved_ns.items():
202            self._setAttributeNS(namespaceURI=self._xmlns_nsuri, 
203                qualifiedName='%s:%s' %(self._xmlns_prefix,prefix), 
204                value=nsuri)
205
206    #############################################
207    #Methods for attributes
208    #############################################
209    def hasAttribute(self, namespaceURI, localName):
210        return self._dom.hasAttr(self._getNode(), name=localName, nsuri=namespaceURI)
211
212    def setAttributeType(self, namespaceURI, localName):
213        '''set xsi:type
214        Keyword arguments:
215            namespaceURI -- namespace of attribute value
216            localName -- name of new attribute value
217
218        '''
219        self.logger.debug('setAttributeType: (%s,%s)', namespaceURI, localName)
220        value = localName
221        if namespaceURI:
222            value = '%s:%s' %(self.getPrefix(namespaceURI),localName)
223
224        xsi_prefix = self.getPrefix(self._xsi_nsuri)
225        self._setAttributeNS(self._xsi_nsuri, '%s:type' %xsi_prefix, value)
226
227    def createAttributeNS(self, namespace, name, value):
228        document = self._getOwnerDocument()
229        attrNode = document.createAttributeNS(namespace, name, value)
230
231    def setAttributeNS(self, namespaceURI, localName, value):
232        '''
233        Keyword arguments:
234            namespaceURI -- namespace of attribute to create, None is for
235                attributes in no namespace.
236            localName -- local name of new attribute
237            value -- value of new attribute
238        ''' 
239        prefix = None
240        if namespaceURI:
241            try:
242                prefix = self.getPrefix(namespaceURI)
243            except KeyError, ex:
244                prefix = 'ns2'
245                self.setNamespaceAttribute(prefix, namespaceURI)
246        qualifiedName = localName
247        if prefix:
248            qualifiedName = '%s:%s' %(prefix, localName)
249        self._setAttributeNS(namespaceURI, qualifiedName, value)
250
251    def setNamespaceAttribute(self, prefix, namespaceURI):
252        '''
253        Keyword arguments:
254            prefix -- xmlns prefix
255            namespaceURI -- value of prefix
256        '''
257        self._setAttributeNS(XMLNS.BASE, 'xmlns:%s' %prefix, namespaceURI)
258
259    #############################################
260    #Methods for elements
261    #############################################
262    def createElementNS(self, namespace, qname):
263        '''
264        Keyword arguments:
265            namespace -- namespace of element to create
266            qname -- qualified name of new element
267        '''
268        document = self._getOwnerDocument()
269        node = document.createElementNS(namespace, qname)
270        return ElementProxy(self.sw, node)
271
272    def createAppendSetElement(self, namespaceURI, localName, prefix=None):
273        '''Create a new element (namespaceURI,name), append it
274           to current node, then set it to be the current node.
275        Keyword arguments:
276            namespaceURI -- namespace of element to create
277            localName -- local name of new element
278            prefix -- if namespaceURI is not defined, declare prefix.  defaults
279                to 'ns1' if left unspecified.
280        '''
281        node = self.createAppendElement(namespaceURI, localName, prefix=None)
282        node=node._getNode()
283        self._setNode(node._getNode())
284
285    def createAppendElement(self, namespaceURI, localName, prefix=None):
286        '''Create a new element (namespaceURI,name), append it
287           to current node, and return the newly created node.
288        Keyword arguments:
289            namespaceURI -- namespace of element to create
290            localName -- local name of new element
291            prefix -- if namespaceURI is not defined, declare prefix.  defaults
292                to 'ns1' if left unspecified.
293        '''
294        declare = False
295        qualifiedName = localName
296        if namespaceURI:
297            try:
298                prefix = self.getPrefix(namespaceURI)
299            except:
300                declare = True
301                prefix = prefix or self._getUniquePrefix()
302            if prefix: 
303                qualifiedName = '%s:%s' %(prefix, localName)
304        node = self.createElementNS(namespaceURI, qualifiedName)
305        if declare:
306            node._setAttributeNS(XMLNS.BASE, 'xmlns:%s' %prefix, namespaceURI)
307        self._appendChild(node=node._getNode())
308        return node
309
310    def createInsertBefore(self, namespaceURI, localName, refChild):
311        qualifiedName = localName
312        prefix = self.getPrefix(namespaceURI)
313        if prefix: 
314            qualifiedName = '%s:%s' %(prefix, localName)
315        node = self.createElementNS(namespaceURI, qualifiedName)
316        self._insertBefore(newChild=node._getNode(), refChild=refChild._getNode())
317        return node
318
319    def getElement(self, namespaceURI, localName):
320        '''
321        Keyword arguments:
322            namespaceURI -- namespace of element
323            localName -- local name of element
324        '''
325        node = self._dom.getElement(self.node, localName, namespaceURI, default=None)
326        if node:
327            return ElementProxy(self.sw, node)
328        return None
329
330    def getAttributeValue(self, namespaceURI, localName):
331        '''
332        Keyword arguments:
333            namespaceURI -- namespace of attribute
334            localName -- local name of attribute
335        '''
336        if self.hasAttribute(namespaceURI, localName):
337            attr = self.node.getAttributeNodeNS(namespaceURI,localName)
338            return attr.value
339        return None
340
341    def getValue(self):
342        return self._dom.getElementText(self.node, preserve_ws=True)   
343
344    #############################################
345    #Methods for text nodes
346    #############################################
347    def createAppendTextNode(self, pyobj):
348        node = self.createTextNode(pyobj)
349        self._appendChild(node=node._getNode())
350        return node
351
352    def createTextNode(self, pyobj):
353        document = self._getOwnerDocument()
354        node = document.createTextNode(pyobj)
355        return ElementProxy(self.sw, node)
356
357    #############################################
358    #Methods for retrieving namespaceURI's
359    #############################################
360    def findNamespaceURI(self, qualifiedName):
361        parts = SplitQName(qualifiedName)
362        element = self._getNode()
363        if len(parts) == 1:
364            return (self._dom.findTargetNS(element), value)
365        return self._dom.findNamespaceURI(parts[0], element)
366
367    def resolvePrefix(self, prefix):
368        element = self._getNode()
369        return self._dom.findNamespaceURI(prefix, element)
370
371    def getSOAPEnvURI(self):
372        return self._soap_env_nsuri
373
374    def isEmpty(self):
375        return not self.node
Note: See TracBrowser for help on using the repository browser.