Package suds :: Module builder
[hide private]
[frames] | no frames]

Source Code for Module suds.builder

  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  The I{builder} module provides an wsdl/xsd defined types factory 
 19  """ 
 20   
 21  from logging import getLogger 
 22  from suds import * 
 23  from suds.sudsobject import Factory 
 24   
 25  log = getLogger(__name__) 
 26   
 27   
28 -class Builder:
29 """ Builder used to construct an object for types defined in the schema """ 30
31 - def __init__(self, resolver):
32 """ 33 @param resolver: A schema object name resolver. 34 @type resolver: L{resolver.Resolver} 35 """ 36 self.resolver = resolver
37
38 - def build(self, name):
39 """ build a an object for the specified typename as defined in the schema """ 40 if isinstance(name, basestring): 41 type = self.resolver.find(name) 42 if type is None: 43 raise TypeNotFound(name) 44 else: 45 type = name 46 cls = type.name 47 if type.mixed(): 48 data = Factory.property(cls) 49 else: 50 data = Factory.object(cls) 51 resolved = type.resolve() 52 md = data.__metadata__ 53 md.sxtype = resolved 54 md.ordering = self.ordering(resolved) 55 history = [] 56 self.add_attributes(data, resolved) 57 for child, ancestry in type.children(): 58 if self.skip_child(child, ancestry): 59 continue 60 self.process(data, child, history[:]) 61 return data
62
63 - def process(self, data, type, history):
64 """ process the specified type then process its children """ 65 if type in history: 66 return 67 if type.enum(): 68 return 69 history.append(type) 70 resolved = type.resolve() 71 value = None 72 if type.unbounded(): 73 value = [] 74 else: 75 if len(resolved) > 0: 76 if resolved.mixed(): 77 value = Factory.property(resolved.name) 78 md = value.__metadata__ 79 md.sxtype = resolved 80 else: 81 value = Factory.object(resolved.name) 82 md = value.__metadata__ 83 md.sxtype = resolved 84 md.ordering = self.ordering(resolved) 85 setattr(data, type.name, value) 86 if value is not None: 87 data = value 88 if not isinstance(data, list): 89 self.add_attributes(data, resolved) 90 for child, ancestry in resolved.children(): 91 if self.skip_child(child, ancestry): 92 continue 93 self.process(data, child, history[:])
94
95 - def add_attributes(self, data, type):
96 """ add required attributes """ 97 for attr, ancestry in type.attributes(): 98 name = '_%s' % attr.name 99 value = attr.get_default() 100 setattr(data, name, value)
101
102 - def skip_child(self, child, ancestry):
103 """ get whether or not to skip the specified child """ 104 if child.any(): return True 105 for x in ancestry: 106 if x.choice(): 107 return True 108 return False
109
110 - def ordering(self, type):
111 """ get the ordering """ 112 result = [] 113 for child, ancestry in type.resolve(): 114 name = child.name 115 if child.name is None: 116 continue 117 if child.isattr(): 118 name = '_%s' % child.name 119 result.append(name) 120 return result
121