1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 from xml.dom import minidom
26
28 """
29 Instances of this class represent individual binary data items
30 associated to an XOP XML document.
31
32 For the XOP specification, see U{http://www.w3.org/TR/xop10/}.
33
34 @author: jmoringe
35 """
37 self._uri = uri
38 self._data = data
39
42
45
46 uri = property(getURI, setURI)
47
50
53
54 data = property(getData, setData)
55
57 if hasattr(self.data, '__length__'):
58 data = '%s of length %d' % (type(self.data).__name__, len(self.data))
59 else:
60 data = self.data
61 return '<%s %s: %s>' \
62 % (type(self).__name__, self.uri, data)
63
66
68 """
69 Instances of this class represent composite XOP structures
70 consisting of an XML document and associated binary data items.
71
72 For the XOP specification, see U{http://www.w3.org/TR/xop10/}.
73
74 @author: jmoringe
75 """
76 - def __init__(self, document, attachments = None):
85
88
93
94 document = property(getDocument, setDocument)
95
97 return self._attachments.values()
98
100 """
101 Set the associated binary data items to L{attachments}.
102
103 @param attachments: Either a C{dict} the keys of which are
104 URIs and the values of which are the
105 binary data items, or a list of either
106 L{Attachment} objects or pairs of the same
107 kind as in the C{dict} case.
108 @type attachments: dict or list
109
110 Example:
111
112 >>> p.attachments = { 'http://foo.bar': bytearray(str('bla')) }
113 ...
114
115 >>> p.attachments = [ Attachment('http://foo.bar', bytearray(str('bla'))) ]
116 ...
117 """
118
119 if isinstance(attachments, dict):
120 attachments = dict( (key, self._makeAttachment(key, value))
121 for (key, value) in attachments.items() )
122
123 elif isinstance(attachments, list):
124 def toPair(item):
125 if isinstance(item, Attachment):
126 return (item.uri, item)
127 else:
128 return item
129 attachments = dict( toPair(item) for item in attachments )
130 else:
131 raise TypeError, attachments
132 self._attachments = attachments
133
134 attachments = property(getAttachments, setAttachments)
135
137 return self._attachments[uri]
138
144
146 """
147 Add L{attachment} to the list of attachments.
148
149 @param attachment: The attachment that should be added.
150 @type attachment: Attachment
151 @raise KeyError: If there already is a attachment for the URI of
152 L{attachment}.
153 """
154 if attachment.uri in self._attachments:
155 raise KeyError, 'duplicate attachment URI: %s' % attachment.uri
156 self._attachments[attachment.uri] = attachment
157
160
162 return '<%s <%s .../> with %s attachment(s)>' \
163 % (type(self).__name__,
164 self.document.documentElement.tagName,
165 len(self._attachments))
166
169
170 from rsb.converter import Converter, registerGlobalConverter, getGlobalConverterMap
171 import rst.xml.XOP_pb2 as pb
172
174 - def __init__(self, attachmentConverter = getGlobalConverterMap(bytearray)):
179
180
182 return self.__attachmentConverter
183
184 attachmentConverter = property(getAttachmentConverter)
185
187 if not isinstance(input, XOP):
188 raise TypeError, input
189
190
191
192 holder = pb.XOP()
193 holder.xml = input.document.toxml(encoding = 'UTF-8')
194 for attachment in input.attachments:
195 attachment_ = holder.attachments.add()
196 attachment_.url = attachment.uri
197
198 data, wire_schema \
199 = self.attachmentConverter \
200 .getConverterForDataType(type(attachment.data)) \
201 .serialize(attachment.data)
202 attachment_.data = str(data)
203 attachment_.wire_schema = wire_schema
204
205
206
207 return holder.SerializeToString(), self.wireSchema
208
210 if not wireSchema == self.wireSchema:
211 raise ValueError("Cannot handle wire-schema %s" % wireSchema)
212
213
214
215
216 holder = pb.XOP()
217 holder.ParseFromString(str(input))
218
219
220
221 package = XOP(document = minidom.parseString(holder.xml))
222 for attachment_ in holder.attachments:
223 data = self.attachmentConverter \
224 .getConverterForWireSchema(attachment_.wire_schema) \
225 .deserialize(attachment_.data, attachment_.wire_schema)
226 package.setAttachment(attachment_.url, data)
227
228 return package
229
230 registerGlobalConverter(XOPConverter())
231
232 import rsb
233 rsb.__defaultParticipantConfig = rsb.ParticipantConfig.fromDefaultSources()
234
235
236