1# This program is free software; you can redistribute it and/or modify
2# it under the terms of the (LGPL) GNU Lesser General Public License as
3# published by the Free Software Foundation; either version 3 of the
4# License, or (at your option) any later version.
5#
6# This program is distributed in the hope that it will be useful,
7# but WITHOUT ANY WARRANTY; without even the implied warranty of
8# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9# GNU Library Lesser General Public License for more details at
10# ( http://www.gnu.org/licenses/lgpl.html ).
11#
12# You should have received a copy of the GNU Lesser General Public License
13# along with this program; if not, write to the Free Software
14# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15# written by: Jeff Ortel ( jortel@redhat.com )
16
17"""
18Support for holding XML document texts that may then be accessed internally by
19suds without having to download them from an external source. Also contains XML
20document content to be distributed alongside the suds library.
21
22"""
23
24import suds
25
26
27soap5_encoding_schema = suds.byte_str("""\
28<?xml version="1.0" encoding="UTF-8"?>
29<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
30    xmlns:tns="http://schemas.xmlsoap.org/soap/encoding/"
31    targetNamespace="http://schemas.xmlsoap.org/soap/encoding/">
32
33 <xs:attribute name="root">
34   <xs:annotation>
35     <xs:documentation>
36       'root' can be used to distinguish serialization roots from other
37       elements that are present in a serialization but are not roots of
38       a serialized value graph
39     </xs:documentation>
40   </xs:annotation>
41   <xs:simpleType>
42     <xs:restriction base="xs:boolean">
43       <xs:pattern value="0|1"/>
44     </xs:restriction>
45   </xs:simpleType>
46 </xs:attribute>
47
48  <xs:attributeGroup name="commonAttributes">
49    <xs:annotation>
50      <xs:documentation>
51        Attributes common to all elements that function as accessors or
52        represent independent (multi-ref) values.  The href attribute is
53        intended to be used in a manner like CONREF.  That is, the element
54        content should be empty iff the href attribute appears
55      </xs:documentation>
56    </xs:annotation>
57    <xs:attribute name="id" type="xs:ID"/>
58    <xs:attribute name="href" type="xs:anyURI"/>
59    <xs:anyAttribute namespace="##other" processContents="lax"/>
60  </xs:attributeGroup>
61
62  <!-- Global Attributes.  The following attributes are intended to be usable via qualified attribute names on any complex type referencing them. -->
63
64  <!-- Array attributes. Needed to give the type and dimensions of an array's contents, and the offset for partially-transmitted arrays. -->
65
66  <xs:simpleType name="arrayCoordinate">
67    <xs:restriction base="xs:string"/>
68  </xs:simpleType>
69
70  <xs:attribute name="arrayType" type="xs:string"/>
71  <xs:attribute name="offset" type="tns:arrayCoordinate"/>
72
73  <xs:attributeGroup name="arrayAttributes">
74    <xs:attribute ref="tns:arrayType"/>
75    <xs:attribute ref="tns:offset"/>
76  </xs:attributeGroup>
77
78  <xs:attribute name="position" type="tns:arrayCoordinate"/>
79
80  <xs:attributeGroup name="arrayMemberAttributes">
81    <xs:attribute ref="tns:position"/>
82  </xs:attributeGroup>
83
84  <xs:group name="Array">
85    <xs:sequence>
86      <xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax"/>
87    </xs:sequence>
88  </xs:group>
89
90  <xs:element name="Array" type="tns:Array"/>
91  <xs:complexType name="Array">
92    <xs:annotation>
93      <xs:documentation>
94       'Array' is a complex type for accessors identified by position
95      </xs:documentation>
96    </xs:annotation>
97    <xs:group ref="tns:Array" minOccurs="0"/>
98    <xs:attributeGroup ref="tns:arrayAttributes"/>
99    <xs:attributeGroup ref="tns:commonAttributes"/>
100  </xs:complexType>
101
102  <!-- 'Struct' is a complex type for accessors identified by name.
103       Constraint: No element may be have the same name as any other,
104       nor may any element have a maxOccurs > 1. -->
105
106  <xs:element name="Struct" type="tns:Struct"/>
107
108  <xs:group name="Struct">
109    <xs:sequence>
110      <xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax"/>
111    </xs:sequence>
112  </xs:group>
113
114  <xs:complexType name="Struct">
115    <xs:group ref="tns:Struct" minOccurs="0"/>
116    <xs:attributeGroup ref="tns:commonAttributes"/>
117  </xs:complexType>
118
119  <!-- 'Base64' can be used to serialize binary data using base64 encoding
120       as defined in RFC2045 but without the MIME line length limitation. -->
121
122  <xs:simpleType name="base64">
123    <xs:restriction base="xs:base64Binary"/>
124  </xs:simpleType>
125
126 <!-- Element declarations corresponding to each of the simple types in the
127      XML Schemas Specification. -->
128
129  <xs:element name="duration" type="tns:duration"/>
130  <xs:complexType name="duration">
131    <xs:simpleContent>
132      <xs:extension base="xs:duration">
133        <xs:attributeGroup ref="tns:commonAttributes"/>
134      </xs:extension>
135    </xs:simpleContent>
136  </xs:complexType>
137
138  <xs:element name="dateTime" type="tns:dateTime"/>
139  <xs:complexType name="dateTime">
140    <xs:simpleContent>
141      <xs:extension base="xs:dateTime">
142        <xs:attributeGroup ref="tns:commonAttributes"/>
143      </xs:extension>
144    </xs:simpleContent>
145  </xs:complexType>
146
147  <xs:element name="NOTATION" type="tns:NOTATION"/>
148  <xs:complexType name="NOTATION">
149    <xs:simpleContent>
150      <xs:extension base="xs:QName">
151        <xs:attributeGroup ref="tns:commonAttributes"/>
152      </xs:extension>
153    </xs:simpleContent>
154  </xs:complexType>
155
156  <xs:element name="time" type="tns:time"/>
157  <xs:complexType name="time">
158    <xs:simpleContent>
159      <xs:extension base="xs:time">
160        <xs:attributeGroup ref="tns:commonAttributes"/>
161      </xs:extension>
162    </xs:simpleContent>
163  </xs:complexType>
164
165  <xs:element name="date" type="tns:date"/>
166  <xs:complexType name="date">
167    <xs:simpleContent>
168      <xs:extension base="xs:date">
169        <xs:attributeGroup ref="tns:commonAttributes"/>
170      </xs:extension>
171    </xs:simpleContent>
172  </xs:complexType>
173
174  <xs:element name="gYearMonth" type="tns:gYearMonth"/>
175  <xs:complexType name="gYearMonth">
176    <xs:simpleContent>
177      <xs:extension base="xs:gYearMonth">
178        <xs:attributeGroup ref="tns:commonAttributes"/>
179      </xs:extension>
180    </xs:simpleContent>
181  </xs:complexType>
182
183  <xs:element name="gYear" type="tns:gYear"/>
184  <xs:complexType name="gYear">
185    <xs:simpleContent>
186      <xs:extension base="xs:gYear">
187        <xs:attributeGroup ref="tns:commonAttributes"/>
188      </xs:extension>
189    </xs:simpleContent>
190  </xs:complexType>
191
192  <xs:element name="gMonthDay" type="tns:gMonthDay"/>
193  <xs:complexType name="gMonthDay">
194    <xs:simpleContent>
195      <xs:extension base="xs:gMonthDay">
196        <xs:attributeGroup ref="tns:commonAttributes"/>
197      </xs:extension>
198    </xs:simpleContent>
199  </xs:complexType>
200
201  <xs:element name="gDay" type="tns:gDay"/>
202  <xs:complexType name="gDay">
203    <xs:simpleContent>
204      <xs:extension base="xs:gDay">
205        <xs:attributeGroup ref="tns:commonAttributes"/>
206      </xs:extension>
207    </xs:simpleContent>
208  </xs:complexType>
209
210  <xs:element name="gMonth" type="tns:gMonth"/>
211  <xs:complexType name="gMonth">
212    <xs:simpleContent>
213      <xs:extension base="xs:gMonth">
214        <xs:attributeGroup ref="tns:commonAttributes"/>
215      </xs:extension>
216    </xs:simpleContent>
217  </xs:complexType>
218
219  <xs:element name="boolean" type="tns:boolean"/>
220  <xs:complexType name="boolean">
221    <xs:simpleContent>
222      <xs:extension base="xs:boolean">
223        <xs:attributeGroup ref="tns:commonAttributes"/>
224      </xs:extension>
225    </xs:simpleContent>
226  </xs:complexType>
227
228  <xs:element name="base64Binary" type="tns:base64Binary"/>
229  <xs:complexType name="base64Binary">
230    <xs:simpleContent>
231      <xs:extension base="xs:base64Binary">
232        <xs:attributeGroup ref="tns:commonAttributes"/>
233      </xs:extension>
234    </xs:simpleContent>
235  </xs:complexType>
236
237  <xs:element name="hexBinary" type="tns:hexBinary"/>
238  <xs:complexType name="hexBinary">
239    <xs:simpleContent>
240     <xs:extension base="xs:hexBinary">
241       <xs:attributeGroup ref="tns:commonAttributes"/>
242     </xs:extension>
243    </xs:simpleContent>
244  </xs:complexType>
245
246  <xs:element name="float" type="tns:float"/>
247  <xs:complexType name="float">
248    <xs:simpleContent>
249      <xs:extension base="xs:float">
250        <xs:attributeGroup ref="tns:commonAttributes"/>
251      </xs:extension>
252    </xs:simpleContent>
253  </xs:complexType>
254
255  <xs:element name="double" type="tns:double"/>
256  <xs:complexType name="double">
257    <xs:simpleContent>
258      <xs:extension base="xs:double">
259        <xs:attributeGroup ref="tns:commonAttributes"/>
260      </xs:extension>
261    </xs:simpleContent>
262  </xs:complexType>
263
264  <xs:element name="anyURI" type="tns:anyURI"/>
265  <xs:complexType name="anyURI">
266    <xs:simpleContent>
267      <xs:extension base="xs:anyURI">
268        <xs:attributeGroup ref="tns:commonAttributes"/>
269      </xs:extension>
270    </xs:simpleContent>
271  </xs:complexType>
272
273  <xs:element name="QName" type="tns:QName"/>
274  <xs:complexType name="QName">
275    <xs:simpleContent>
276      <xs:extension base="xs:QName">
277        <xs:attributeGroup ref="tns:commonAttributes"/>
278      </xs:extension>
279    </xs:simpleContent>
280  </xs:complexType>
281
282  <xs:element name="string" type="tns:string"/>
283  <xs:complexType name="string">
284    <xs:simpleContent>
285      <xs:extension base="xs:string">
286        <xs:attributeGroup ref="tns:commonAttributes"/>
287      </xs:extension>
288    </xs:simpleContent>
289  </xs:complexType>
290
291  <xs:element name="normalizedString" type="tns:normalizedString"/>
292  <xs:complexType name="normalizedString">
293    <xs:simpleContent>
294      <xs:extension base="xs:normalizedString">
295        <xs:attributeGroup ref="tns:commonAttributes"/>
296      </xs:extension>
297    </xs:simpleContent>
298  </xs:complexType>
299
300  <xs:element name="token" type="tns:token"/>
301  <xs:complexType name="token">
302    <xs:simpleContent>
303      <xs:extension base="xs:token">
304        <xs:attributeGroup ref="tns:commonAttributes"/>
305      </xs:extension>
306    </xs:simpleContent>
307  </xs:complexType>
308
309  <xs:element name="language" type="tns:language"/>
310  <xs:complexType name="language">
311    <xs:simpleContent>
312      <xs:extension base="xs:language">
313        <xs:attributeGroup ref="tns:commonAttributes"/>
314      </xs:extension>
315    </xs:simpleContent>
316  </xs:complexType>
317
318  <xs:element name="Name" type="tns:Name"/>
319  <xs:complexType name="Name">
320    <xs:simpleContent>
321      <xs:extension base="xs:Name">
322        <xs:attributeGroup ref="tns:commonAttributes"/>
323      </xs:extension>
324    </xs:simpleContent>
325  </xs:complexType>
326
327  <xs:element name="NMTOKEN" type="tns:NMTOKEN"/>
328  <xs:complexType name="NMTOKEN">
329    <xs:simpleContent>
330      <xs:extension base="xs:NMTOKEN">
331        <xs:attributeGroup ref="tns:commonAttributes"/>
332      </xs:extension>
333    </xs:simpleContent>
334  </xs:complexType>
335
336  <xs:element name="NCName" type="tns:NCName"/>
337  <xs:complexType name="NCName">
338    <xs:simpleContent>
339      <xs:extension base="xs:NCName">
340        <xs:attributeGroup ref="tns:commonAttributes"/>
341      </xs:extension>
342    </xs:simpleContent>
343  </xs:complexType>
344
345  <xs:element name="NMTOKENS" type="tns:NMTOKENS"/>
346  <xs:complexType name="NMTOKENS">
347    <xs:simpleContent>
348      <xs:extension base="xs:NMTOKENS">
349        <xs:attributeGroup ref="tns:commonAttributes"/>
350      </xs:extension>
351    </xs:simpleContent>
352  </xs:complexType>
353
354  <xs:element name="ID" type="tns:ID"/>
355  <xs:complexType name="ID">
356    <xs:simpleContent>
357      <xs:extension base="xs:ID">
358        <xs:attributeGroup ref="tns:commonAttributes"/>
359      </xs:extension>
360    </xs:simpleContent>
361  </xs:complexType>
362
363  <xs:element name="IDREF" type="tns:IDREF"/>
364  <xs:complexType name="IDREF">
365    <xs:simpleContent>
366      <xs:extension base="xs:IDREF">
367        <xs:attributeGroup ref="tns:commonAttributes"/>
368      </xs:extension>
369    </xs:simpleContent>
370  </xs:complexType>
371
372  <xs:element name="ENTITY" type="tns:ENTITY"/>
373  <xs:complexType name="ENTITY">
374    <xs:simpleContent>
375      <xs:extension base="xs:ENTITY">
376        <xs:attributeGroup ref="tns:commonAttributes"/>
377      </xs:extension>
378    </xs:simpleContent>
379  </xs:complexType>
380
381  <xs:element name="IDREFS" type="tns:IDREFS"/>
382  <xs:complexType name="IDREFS">
383    <xs:simpleContent>
384      <xs:extension base="xs:IDREFS">
385        <xs:attributeGroup ref="tns:commonAttributes"/>
386      </xs:extension>
387    </xs:simpleContent>
388  </xs:complexType>
389
390  <xs:element name="ENTITIES" type="tns:ENTITIES"/>
391  <xs:complexType name="ENTITIES">
392    <xs:simpleContent>
393      <xs:extension base="xs:ENTITIES">
394        <xs:attributeGroup ref="tns:commonAttributes"/>
395      </xs:extension>
396    </xs:simpleContent>
397  </xs:complexType>
398
399  <xs:element name="decimal" type="tns:decimal"/>
400  <xs:complexType name="decimal">
401    <xs:simpleContent>
402      <xs:extension base="xs:decimal">
403        <xs:attributeGroup ref="tns:commonAttributes"/>
404      </xs:extension>
405    </xs:simpleContent>
406  </xs:complexType>
407
408  <xs:element name="integer" type="tns:integer"/>
409  <xs:complexType name="integer">
410    <xs:simpleContent>
411      <xs:extension base="xs:integer">
412        <xs:attributeGroup ref="tns:commonAttributes"/>
413      </xs:extension>
414    </xs:simpleContent>
415  </xs:complexType>
416
417  <xs:element name="nonPositiveInteger" type="tns:nonPositiveInteger"/>
418  <xs:complexType name="nonPositiveInteger">
419    <xs:simpleContent>
420      <xs:extension base="xs:nonPositiveInteger">
421        <xs:attributeGroup ref="tns:commonAttributes"/>
422      </xs:extension>
423    </xs:simpleContent>
424  </xs:complexType>
425
426  <xs:element name="negativeInteger" type="tns:negativeInteger"/>
427  <xs:complexType name="negativeInteger">
428    <xs:simpleContent>
429      <xs:extension base="xs:negativeInteger">
430        <xs:attributeGroup ref="tns:commonAttributes"/>
431      </xs:extension>
432    </xs:simpleContent>
433  </xs:complexType>
434
435  <xs:element name="long" type="tns:long"/>
436  <xs:complexType name="long">
437    <xs:simpleContent>
438      <xs:extension base="xs:long">
439        <xs:attributeGroup ref="tns:commonAttributes"/>
440      </xs:extension>
441    </xs:simpleContent>
442  </xs:complexType>
443
444  <xs:element name="int" type="tns:int"/>
445  <xs:complexType name="int">
446    <xs:simpleContent>
447      <xs:extension base="xs:int">
448        <xs:attributeGroup ref="tns:commonAttributes"/>
449      </xs:extension>
450    </xs:simpleContent>
451  </xs:complexType>
452
453  <xs:element name="short" type="tns:short"/>
454  <xs:complexType name="short">
455    <xs:simpleContent>
456      <xs:extension base="xs:short">
457        <xs:attributeGroup ref="tns:commonAttributes"/>
458      </xs:extension>
459    </xs:simpleContent>
460  </xs:complexType>
461
462  <xs:element name="byte" type="tns:byte"/>
463  <xs:complexType name="byte">
464    <xs:simpleContent>
465      <xs:extension base="xs:byte">
466        <xs:attributeGroup ref="tns:commonAttributes"/>
467      </xs:extension>
468    </xs:simpleContent>
469  </xs:complexType>
470
471  <xs:element name="nonNegativeInteger" type="tns:nonNegativeInteger"/>
472  <xs:complexType name="nonNegativeInteger">
473    <xs:simpleContent>
474      <xs:extension base="xs:nonNegativeInteger">
475        <xs:attributeGroup ref="tns:commonAttributes"/>
476      </xs:extension>
477    </xs:simpleContent>
478  </xs:complexType>
479
480  <xs:element name="unsignedLong" type="tns:unsignedLong"/>
481  <xs:complexType name="unsignedLong">
482    <xs:simpleContent>
483      <xs:extension base="xs:unsignedLong">
484        <xs:attributeGroup ref="tns:commonAttributes"/>
485      </xs:extension>
486    </xs:simpleContent>
487  </xs:complexType>
488
489  <xs:element name="unsignedInt" type="tns:unsignedInt"/>
490  <xs:complexType name="unsignedInt">
491    <xs:simpleContent>
492      <xs:extension base="xs:unsignedInt">
493        <xs:attributeGroup ref="tns:commonAttributes"/>
494      </xs:extension>
495    </xs:simpleContent>
496  </xs:complexType>
497
498  <xs:element name="unsignedShort" type="tns:unsignedShort"/>
499  <xs:complexType name="unsignedShort">
500    <xs:simpleContent>
501      <xs:extension base="xs:unsignedShort">
502        <xs:attributeGroup ref="tns:commonAttributes"/>
503      </xs:extension>
504    </xs:simpleContent>
505  </xs:complexType>
506
507  <xs:element name="unsignedByte" type="tns:unsignedByte"/>
508  <xs:complexType name="unsignedByte">
509    <xs:simpleContent>
510      <xs:extension base="xs:unsignedByte">
511        <xs:attributeGroup ref="tns:commonAttributes"/>
512      </xs:extension>
513    </xs:simpleContent>
514  </xs:complexType>
515
516  <xs:element name="positiveInteger" type="tns:positiveInteger"/>
517  <xs:complexType name="positiveInteger">
518    <xs:simpleContent>
519      <xs:extension base="xs:positiveInteger">
520        <xs:attributeGroup ref="tns:commonAttributes"/>
521      </xs:extension>
522    </xs:simpleContent>
523  </xs:complexType>
524
525  <xs:element name="anyType"/>
526</xs:schema>
527""")
528
529
530class DocumentStore:
531    """
532    The I{suds} document store provides a local repository for XML documents.
533
534    @cvar protocol: The URL protocol for the store.
535    @type protocol: str
536    @cvar store: The mapping of URL location to documents.
537    @type store: dict
538    """
539
540    def __init__(self, *args, **kwargs):
541        self.__store = {
542            'schemas.xmlsoap.org/soap/encoding/':soap5_encoding_schema}
543        self.update = self.__store.update
544        self.update(*args, **kwargs)
545
546    def __len__(self):
547        # Implementation note:
548        #   We can not implement '__len__' as simply self.__store.__len__, as
549        # we do for 'update' because that causes py2to3 conversion to fail.
550        #                                            (08.05.2013.) (Jurko)
551        return len(self.__store)
552
553    def open(self, url):
554        """
555        Open a document at the specified URL.
556
557        Missing documents referenced using the internal 'suds' protocol are
558        reported by raising an exception. For other protocols, None is returned
559        instead.
560
561        @param url: A document URL.
562        @type url: str
563        @return: Document content or None if not found.
564        @rtype: bytes
565        """
566        protocol, location = self.__split(url)
567        content = self.__find(location)
568        if protocol == 'suds' and content is None:
569            raise Exception('location "%s" not in document store' % location)
570        return content
571
572    def __find(self, location):
573        """
574        Find the specified location in the store.
575        @param location: The I{location} part of a URL.
576        @type location: str
577        @return: Document content or None if not found.
578        @rtype: bytes
579        """
580        return self.__store.get(location)
581
582    def __split(self, url):
583        """
584        Split the URL into I{protocol} and I{location}
585        @param url: A URL.
586        @param url: str
587        @return: (I{url}, I{location})
588        @rtype: tuple
589        """
590        parts = url.split('://', 1)
591        if len(parts) == 2:
592            return parts
593        return None, url
594
595
596defaultDocumentStore = DocumentStore()
597