Package suds :: Package mx :: Module appender
[hide private]
[frames] | no frames]

Source Code for Module suds.mx.appender

  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  """ 
 18  Provides appender classes for I{marshalling}. 
 19  """ 
 20   
 21  from logging import getLogger 
 22  from suds import * 
 23  from suds.mx import * 
 24  from suds.sudsobject import footprint 
 25  from suds.sudsobject import Object, Property 
 26  from suds.sax.element import Element 
 27  from suds.sax.text import Text 
 28  from copy import deepcopy 
 29   
 30  log = getLogger(__name__) 
 31   
32 -class Matcher:
33 """ 34 Appender matcher. 35 @ivar cls: A class object. 36 @type cls: I{classobj} 37 """ 38
39 - def __init__(self, cls):
40 """ 41 @param cls: A class object. 42 @type cls: I{classobj} 43 """ 44 self.cls = cls
45
46 - def __eq__(self, x):
47 if self.cls is None: 48 return ( x is None ) 49 else: 50 return isinstance(x, self.cls)
51 52
53 -class ContentAppender:
54 """ 55 Appender used to add content to marshalled objects. 56 @ivar default: The default appender. 57 @type default: L{Appender} 58 @ivar appenders: A I{table} of appenders mapped by class. 59 @type appenders: I{table} 60 """ 61
62 - def __init__(self, marshaller):
63 """ 64 @param marshaller: A marshaller. 65 @type marshaller: L{suds.mx.core.Core} 66 """ 67 self.default = PrimativeAppender(marshaller) 68 self.appenders = ( 69 (Matcher(None), 70 NoneAppender(marshaller)), 71 (Matcher(null), 72 NoneAppender(marshaller)), 73 (Matcher(Property), 74 PropertyAppender(marshaller)), 75 (Matcher(Object), 76 ObjectAppender(marshaller)), 77 (Matcher(Element), 78 ElementAppender(marshaller)), 79 (Matcher(Text), 80 TextAppender(marshaller)), 81 (Matcher(list), 82 ListAppender(marshaller)), 83 (Matcher(tuple), 84 ListAppender(marshaller)), 85 (Matcher(dict), 86 DictAppender(marshaller)), 87 )
88
89 - def append(self, parent, content):
90 """ 91 Select an appender and append the content to parent. 92 @param parent: A parent node. 93 @type parent: L{Element} 94 @param content: The content to append. 95 @type content: L{Content} 96 """ 97 appender = self.default 98 for a in self.appenders: 99 if a[0] == content.value: 100 appender = a[1] 101 break 102 appender.append(parent, content)
103 104
105 -class Appender:
106 """ 107 An appender used by the marshaller to append content. 108 @ivar marshaller: A marshaller. 109 @type marshaller: L{suds.mx.core.Core} 110 """ 111
112 - def __init__(self, marshaller):
113 """ 114 @param marshaller: A marshaller. 115 @type marshaller: L{suds.mx.core.Core} 116 """ 117 self.marshaller = marshaller
118
119 - def node(self, content):
120 """ 121 Create and return an XML node that is qualified 122 using the I{type}. Also, make sure all referenced namespace 123 prefixes are declared. 124 @param content: The content for which proccessing has ended. 125 @type content: L{Object} 126 @return: A new node. 127 @rtype: L{Element} 128 """ 129 return self.marshaller.node(content)
130
131 - def setnil(self, node, content):
132 """ 133 Set the value of the I{node} to nill. 134 @param node: A I{nil} node. 135 @type node: L{Element} 136 @param content: The content for which proccessing has ended. 137 @type content: L{Object} 138 """ 139 self.marshaller.setnil(node, content)
140
141 - def setdefault(self, node, content):
142 """ 143 Set the value of the I{node} to a default value. 144 @param node: A I{nil} node. 145 @type node: L{Element} 146 @param content: The content for which proccessing has ended. 147 @type content: L{Object} 148 @return: The default. 149 """ 150 return self.marshaller.setdefault(node, content)
151
152 - def optional(self, content):
153 """ 154 Get whether the specified content is optional. 155 @param content: The content which to check. 156 @type content: L{Content} 157 """ 158 return self.marshaller.optional(content)
159
160 - def suspend(self, content):
161 """ 162 Notify I{marshaller} that appending this content has suspended. 163 @param content: The content for which proccessing has been suspended. 164 @type content: L{Object} 165 """ 166 self.marshaller.suspend(content)
167
168 - def resume(self, content):
169 """ 170 Notify I{marshaller} that appending this content has resumed. 171 @param content: The content for which proccessing has been resumed. 172 @type content: L{Object} 173 """ 174 self.marshaller.resume(content)
175
176 - def append(self, parent, content):
177 """ 178 Append the specified L{content} to the I{parent}. 179 @param content: The content to append. 180 @type content: L{Object} 181 """ 182 self.marshaller.append(parent, content)
183 184
185 -class PrimativeAppender(Appender):
186 """ 187 An appender for python I{primative} types. 188 """ 189
190 - def append(self, parent, content):
191 if content.tag.startswith('_'): 192 attr = content.tag[1:] 193 value = tostr(content.value) 194 if value: 195 parent.set(attr, value) 196 else: 197 child = self.node(content) 198 child.setText(tostr(content.value)) 199 parent.append(child)
200 201
202 -class NoneAppender(Appender):
203 """ 204 An appender for I{None} values. 205 """ 206
207 - def append(self, parent, content):
208 child = self.node(content) 209 default = self.setdefault(child, content) 210 if default is None: 211 self.setnil(child, content) 212 parent.append(child)
213 214
215 -class PropertyAppender(Appender):
216 """ 217 A L{Property} appender. 218 """ 219
220 - def append(self, parent, content):
221 p = content.value 222 child = self.node(content) 223 child.setText(p.get()) 224 parent.append(child) 225 for item in p.items(): 226 cont = Content(tag=item[0], value=item[1]) 227 Appender.append(self, child, cont)
228 229
230 -class ObjectAppender(Appender):
231 """ 232 An L{Object} appender. 233 """ 234
235 - def append(self, parent, content):
236 object = content.value 237 if self.optional(content) and footprint(object) == 0: 238 return 239 child = self.node(content) 240 parent.append(child) 241 for item in object: 242 cont = Content(tag=item[0], value=item[1]) 243 Appender.append(self, child, cont)
244 245
246 -class DictAppender(Appender):
247 """ 248 An python I{dict} appender. 249 """ 250
251 - def append(self, parent, content):
252 d = content.value 253 if self.optional(content) and len(d) == 0: 254 return 255 child = self.node(content) 256 parent.append(child) 257 for item in d.items(): 258 cont = Content(tag=item[0], value=item[1]) 259 Appender.append(self, child, cont)
260 261
262 -class ElementWrapper(Element):
263 """ 264 Element wrapper. 265 """ 266
267 - def __init__(self, content):
268 Element.__init__(self, content.name, content.parent) 269 self.__content = content
270
271 - def str(self, indent=0):
272 return self.__content.str(indent)
273 274
275 -class ElementAppender(Appender):
276 """ 277 An appender for I{Element} types. 278 """ 279
280 - def append(self, parent, content):
281 if content.tag.startswith('_'): 282 raise Exception('raw XML not valid as attribute value') 283 child = ElementWrapper(content.value) 284 parent.append(child)
285 286
287 -class ListAppender(Appender):
288 """ 289 A list/tuple appender. 290 """ 291
292 - def append(self, parent, content):
293 collection = content.value 294 if len(collection): 295 self.suspend(content) 296 for item in collection: 297 cont = Content(tag=content.tag, value=item) 298 Appender.append(self, parent, cont) 299 self.resume(content)
300 301
302 -class TextAppender(Appender):
303 """ 304 An appender for I{Text} values. 305 """ 306
307 - def append(self, parent, content):
308 if content.tag.startswith('_'): 309 attr = content.tag[1:] 310 value = tostr(content.value) 311 if value: 312 parent.set(attr, value) 313 else: 314 child = self.node(content) 315 child.setText(content.value) 316 parent.append(child)
317