• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

contrib/opal/ZSI/ZSI/TCcompound.py

00001 #! /usr/bin/env python
00002 # $Header$
00003 '''Compound typecodes.
00004 '''
00005 
00006 from ZSI import _copyright, _children, _child_elements, \
00007     _inttypes, _stringtypes, _seqtypes, _find_arraytype, _find_href, \
00008     _find_type, _find_xmlns_prefix, _get_idstr, EvaluateException, \
00009     ParseException
00010     
00011 from TC import _get_element_nsuri_name, \
00012      _get_xsitype, TypeCode, Any, AnyElement, AnyType, \
00013      Nilled, UNBOUNDED
00014     
00015 from schema import GED, ElementDeclaration, TypeDefinition, \
00016     _get_substitute_element, _get_type_definition, _is_substitute_element
00017 
00018 from ZSI.wstools.Namespaces import SCHEMA, SOAP
00019 from ZSI.wstools.Utility import SplitQName
00020 from ZSI.wstools.logging import getLogger as _GetLogger
00021 import re, types
00022 from copy import copy as _copy
00023 
00024 _find_arrayoffset = lambda E: E.getAttributeNS(SOAP.ENC, "offset")
00025 _find_arrayposition = lambda E: E.getAttributeNS(SOAP.ENC, "position")
00026 
00027 _offset_pat = re.compile(r'\[[0-9]+\]')
00028 _position_pat = _offset_pat
00029 
00030 def _check_typecode_list(ofwhat, tcname):
00031     '''Check a list of typecodes for compliance with Struct
00032     requirements.'''
00033     for o in ofwhat:
00034         if callable(o): #skip if _Mirage
00035             continue
00036         if not isinstance(o, TypeCode):
00037             raise TypeError(
00038                 tcname + ' ofwhat outside the TypeCode hierarchy, ' +
00039                 str(o.__class__))
00040         if o.pname is None and not isinstance(o, AnyElement):
00041             raise TypeError(tcname + ' element ' + str(o) + ' has no name')
00042 
00043 
00044 def _get_type_or_substitute(typecode, pyobj, sw, elt):
00045     '''return typecode or substitute type for wildcard or
00046     derived type.  For serialization only.
00047     '''
00048     sub = getattr(pyobj, 'typecode', typecode)
00049     if sub is typecode or sub is None:
00050         return typecode
00051 
00052     # Element WildCard
00053     if isinstance(typecode, AnyElement):
00054         return sub
00055  
00056     # Global Element Declaration
00057     if isinstance(sub, ElementDeclaration):
00058         if (typecode.nspname,typecode.pname) == (sub.nspname,sub.pname):
00059             raise TypeError(\
00060                 'bad usage, failed to serialize element reference (%s, %s), in: %s' %
00061                  (typecode.nspname, typecode.pname, sw.Backtrace(elt),))
00062 
00063         # check substitutionGroup 
00064         if _is_substitute_element(typecode, sub):
00065             return sub
00066 
00067         raise TypeError(\
00068             'failed to serialize (%s, %s) illegal sub GED (%s,%s): %s' %
00069              (typecode.nspname, typecode.pname, sub.nspname, sub.pname,
00070               sw.Backtrace(elt),))
00071 
00072     # Local Element
00073     if not isinstance(typecode, AnyType) and not isinstance(sub, typecode.__class__):
00074         raise TypeError(\
00075             'failed to serialize substitute %s for %s,  not derivation: %s' %
00076              (sub, typecode, sw.Backtrace(elt),))
00077 
00078     # Make our substitution type match the elements facets,
00079     # since typecode is created for a single existing pyobj
00080     # some facets are irrelevant.
00081     sub = _copy(sub)
00082     sub.nspname = typecode.nspname
00083     sub.pname = typecode.pname
00084     sub.aname = typecode.aname
00085     sub.minOccurs = sub.maxOccurs = 1
00086     return sub
00087 
00088 
00089         
00090 class ComplexType(TypeCode):
00091     '''Represents an element of complexType, potentially containing other 
00092     elements.
00093     '''
00094     logger = _GetLogger('ZSI.TCcompound.ComplexType')
00095     
00096     def __init__(self, pyclass, ofwhat, pname=None, inorder=False, inline=False,
00097     mutable=True, mixed=False, mixed_aname='_text', **kw):
00098         '''pyclass -- the Python class to hold the fields
00099         ofwhat -- a list of fields to be in the complexType
00100         inorder -- fields must be in exact order or not
00101         inline -- don't href/id when serializing
00102         mutable -- object could change between multiple serializations
00103         type -- the (URI,localname) of the datatype
00104         mixed -- mixed content model? True/False
00105         mixed_aname -- if mixed is True, specify text content here. Default _text
00106         '''
00107         TypeCode.__init__(self, pname, pyclass=pyclass, **kw)
00108         self.inorder = inorder
00109         self.inline = inline
00110         self.mutable = mutable
00111         self.mixed = mixed
00112         self.mixed_aname = None
00113         if mixed is True:
00114             self.mixed_aname = mixed_aname
00115 
00116         if self.mutable is True: self.inline = True
00117         self.type = kw.get('type') or _get_xsitype(self)
00118         t = type(ofwhat)
00119         if t not in _seqtypes:
00120             raise TypeError(
00121                 'Struct ofwhat must be list or sequence, not ' + str(t))
00122         self.ofwhat = tuple(ofwhat)
00123         if TypeCode.typechecks:
00124             # XXX Not sure how to determine if new-style class..
00125             if self.pyclass is not None and \
00126                 type(self.pyclass) is not types.ClassType and not isinstance(self.pyclass, object):
00127                 raise TypeError('pyclass must be None or an old-style/new-style class, not ' +
00128                         str(type(self.pyclass)))
00129             _check_typecode_list(self.ofwhat, 'ComplexType')
00130 
00131     def parse(self, elt, ps):
00132         debug = self.logger.debugOn()
00133         debug and self.logger.debug('parse')
00134         
00135         xtype = self.checkname(elt, ps)
00136         if self.type and xtype not in [ self.type, (None,None) ]:
00137             if not isinstance(self, TypeDefinition):
00138                 raise EvaluateException(\
00139                     'ComplexType for %s has wrong type(%s), looking for %s' %
00140                         (self.pname, self.checktype(elt,ps), self.type), 
00141                                         ps.Backtrace(elt))
00142             else:
00143                 #TODO: mabye change MRO to handle this 
00144                 debug and self.logger.debug('delegate to substitute type')
00145                 what = TypeDefinition.getSubstituteType(self, elt, ps)
00146                 return what.parse(elt, ps)
00147             
00148         href = _find_href(elt)
00149         if href:
00150             if _children(elt):
00151                 raise EvaluateException('Struct has content and HREF',
00152                         ps.Backtrace(elt))
00153             elt = ps.FindLocalHREF(href, elt)
00154         c = _child_elements(elt)
00155         count = len(c)
00156         if self.nilled(elt, ps): return Nilled
00157 
00158         # Create the object.
00159         v = {}
00160 
00161         # parse all attributes contained in attribute_typecode_dict (user-defined attributes),
00162         # the values (if not None) will be keyed in self.attributes dictionary.
00163         attributes = self.parse_attributes(elt, ps)
00164         if attributes:
00165             v[self.attrs_aname] = attributes
00166 
00167         #MIXED
00168         if self.mixed is True:
00169             v[self.mixed_aname] = self.simple_value(elt,ps, mixed=True)
00170 
00171         # Clone list of kids (we null it out as we process)
00172         c, crange = c[:], range(len(c))
00173         # Loop over all items we're expecting
00174         
00175         if debug:
00176             self.logger.debug("ofwhat: %s",str(self.ofwhat))
00177             
00178         any = None
00179         for i,what in [ (i, self.ofwhat[i]) for i in range(len(self.ofwhat)) ]:
00180             
00181             # retrieve typecode if it is hidden
00182             if callable(what): what = what()
00183             
00184             # Loop over all available kids
00185             if debug: 
00186                 self.logger.debug("what: (%s,%s)", what.nspname, what.pname)
00187                 
00188             for j,c_elt in [ (j, c[j]) for j in crange if c[j] ]:
00189                 # Parse value, and mark this one done. 
00190                 if debug:
00191                     self.logger.debug("child node: (%s,%s)", c_elt.namespaceURI, c_elt.tagName)
00192 
00193                 match = False
00194                 if what.name_match(c_elt):
00195                     match = True
00196                     value = what.parse(c_elt, ps)
00197                 else:
00198                     # substitutionGroup head must be a global element declaration
00199                     # if successful delegate to matching GED
00200                     subwhat = _get_substitute_element(what, c_elt, ps)
00201                     if subwhat:
00202                         match = True
00203                         value = subwhat.parse(c_elt, ps)
00204 
00205                     if debug: 
00206                         self.logger.debug("substitutionGroup: %s", subwhat)
00207 
00208                 if match:
00209                     if what.maxOccurs > 1:
00210                         if v.has_key(what.aname):
00211                             v[what.aname].append(value)
00212                         else:
00213                             v[what.aname] = [value]
00214                         c[j] = None
00215                         continue
00216                     else:
00217                         v[what.aname] = value
00218                     c[j] = None
00219                     break
00220 
00221                 if debug:
00222                     self.logger.debug("no element (%s,%s)", what.nspname, what.pname)
00223 
00224                 # No match; if it was supposed to be here, that's an error.
00225                 if self.inorder is True and i == j:
00226                     raise EvaluateException('Out of order complexType',
00227                             ps.Backtrace(c_elt))
00228             else:
00229                 # only supporting 1 <any> declaration in content.
00230                 if isinstance(what,AnyElement):
00231                     any = what
00232                 elif hasattr(what, 'default'):
00233                     v[what.aname] = what.default
00234                 elif what.minOccurs > 0 and not v.has_key(what.aname):
00235                     raise EvaluateException('Element "' + what.aname + \
00236                         '" missing from complexType', ps.Backtrace(elt))
00237 
00238         # Look for wildcards and unprocessed children
00239         # XXX Stick all this stuff in "any", hope for no collisions
00240         if any is not None:
00241             occurs = 0
00242             v[any.aname] = []
00243             for j,c_elt in [ (j, c[j]) for j in crange if c[j] ]:
00244                 value = any.parse(c_elt, ps)
00245                 if any.maxOccurs == UNBOUNDED or any.maxOccurs > 1:
00246                     v[any.aname].append(value)
00247                 else:
00248                     v[any.aname] = value
00249 
00250                 occurs += 1
00251 
00252             # No such thing as nillable <any>
00253             if any.maxOccurs == 1 and occurs == 0:
00254                 v[any.aname] = None
00255             elif occurs < any.minOccurs or (any.maxOccurs!=UNBOUNDED and any.maxOccurs<occurs):
00256                 raise EvaluateException('occurances of <any> elements(#%d) bound by (%d,%s)' %(
00257                     occurs, any.minOccurs,str(any.maxOccurs)), ps.Backtrace(elt))
00258 
00259         if not self.pyclass: 
00260             return v
00261 
00262         # type definition must be informed of element tag (nspname,pname),
00263         # element declaration is initialized with a tag.
00264         try:
00265             pyobj = self.pyclass()
00266         except Exception, e:
00267             raise TypeError("Constructing element (%s,%s) with pyclass(%s), %s" \
00268                 %(self.nspname, self.pname, self.pyclass.__name__, str(e)))
00269         for key in v.keys():
00270             setattr(pyobj, key, v[key])
00271         return pyobj
00272 
00273     def serialize(self, elt, sw, pyobj, inline=False, name=None, **kw):
00274         if inline or self.inline:
00275             self.cb(elt, sw, pyobj, name=name, **kw)
00276         else:
00277             objid = _get_idstr(pyobj)
00278             ns,n = self.get_name(name, objid)
00279             el = elt.createAppendElement(ns, n)
00280             el.setAttributeNS(None, 'href', "#%s" %objid)
00281             sw.AddCallback(self.cb, elt, sw, pyobj)
00282 
00283     def cb(self, elt, sw, pyobj, name=None, **kw):
00284         debug = self.logger.debugOn()
00285         if debug:
00286             self.logger.debug("cb: %s" %str(self.ofwhat))
00287 
00288         objid = _get_idstr(pyobj)
00289         ns,n = self.get_name(name, objid)
00290         if pyobj is None:
00291             if self.nillable is True:
00292                 elem = elt.createAppendElement(ns, n)
00293                 self.serialize_as_nil(elem)
00294                 return
00295             raise EvaluateException, 'element(%s,%s) is not nillable(%s)' %(
00296                 self.nspname,self.pname,self.nillable)
00297 
00298         if self.mutable is False and sw.Known(pyobj): 
00299             return
00300         
00301         if debug:
00302             self.logger.debug("element: (%s, %s)", str(ns), n)
00303             
00304         if n is not None:
00305             elem = elt.createAppendElement(ns, n)
00306             self.set_attributes(elem, pyobj)
00307             if kw.get('typed', self.typed) is True:
00308                 self.set_attribute_xsi_type(elem)
00309 
00310             #MIXED For now just stick it in front.
00311             if self.mixed is True and self.mixed_aname is not None:
00312                if hasattr(pyobj, self.mixed_aname):
00313                    textContent = getattr(pyobj, self.mixed_aname)
00314                    if hasattr(textContent, 'typecode'):
00315                        textContent.typecode.serialize_text_node(elem, sw, textContent)
00316                    elif type(textContent) in _stringtypes:
00317                        if debug:
00318                            self.logger.debug("mixed text content:\n\t%s", 
00319                                              textContent)
00320                        elem.createAppendTextNode(textContent)
00321                    else:
00322                        raise EvaluateException('mixed test content in element (%s,%s) must be a string type' %(
00323                            self.nspname,self.pname), sw.Backtrace(elt))
00324                else:
00325                    if debug:
00326                        self.logger.debug("mixed NO text content in %s", 
00327                                          self.mixed_aname)
00328         else:
00329             #For information items w/o tagNames 
00330             #  ie. model groups,SOAP-ENC:Header
00331             elem = elt
00332 
00333         if self.inline:
00334             pass
00335         elif not self.inline and self.unique:
00336             raise EvaluateException('Not inline, but unique makes no sense. No href/id.',
00337                 sw.Backtrace(elt))
00338         elif n is not None:
00339             self.set_attribute_id(elem, objid)
00340 
00341         if self.pyclass and type(self.pyclass) is type:
00342             f = lambda attr: getattr(pyobj, attr, None)
00343         elif self.pyclass:
00344             d = pyobj.__dict__
00345             f = lambda attr: d.get(attr)
00346         else:
00347             d = pyobj
00348             f = lambda attr: pyobj.get(attr)
00349             if TypeCode.typechecks and type(d) != types.DictType:
00350                 raise TypeError("Classless complexType didn't get dictionary")
00351 
00352         indx, lenofwhat = 0, len(self.ofwhat)
00353         if debug:
00354             self.logger.debug('element declaration (%s,%s)', self.nspname, 
00355                               self.pname)
00356             if self.type:
00357                 self.logger.debug('xsi:type definition (%s,%s)', self.type[0], 
00358                                   self.type[1])
00359             else:
00360                 self.logger.warning('NO xsi:type')
00361 
00362         while indx < lenofwhat:
00363             occurs = 0
00364             what = self.ofwhat[indx]
00365             
00366             # retrieve typecode if hidden
00367             if callable(what): what = what()
00368             
00369             if debug:
00370                 self.logger.debug('serialize what -- %s', 
00371                                   what.__class__.__name__)
00372 
00373             # No way to order <any> instances, so just grab any unmatched
00374             # anames and serialize them.  Only support one <any> in all content.
00375             # Must be self-describing instances
00376 
00377             # Regular handling of declared elements
00378             aname = what.aname
00379             v = f(aname)
00380             indx += 1
00381             if what.minOccurs == 0 and v is None: 
00382                 continue
00383 
00384             # Default to typecode, if self-describing instance, and check 
00385             # to make sure it is derived from what.
00386             whatTC = what
00387             if whatTC.maxOccurs > 1 and v is not None:
00388                 if type(v) not in _seqtypes:
00389                     raise EvaluateException('pyobj (%s,%s), aname "%s": maxOccurs %s, expecting a %s' %(
00390                          self.nspname,self.pname,what.aname,whatTC.maxOccurs,_seqtypes), 
00391                          sw.Backtrace(elt))
00392 
00393                 for v2 in v: 
00394                     occurs += 1
00395                     if occurs > whatTC.maxOccurs:
00396                         raise EvaluateException('occurances (%d) exceeded maxOccurs(%d) for <%s>' %(
00397                                 occurs, whatTC.maxOccurs, what.pname), 
00398                                 sw.Backtrace(elt))
00399                         
00400                     what = _get_type_or_substitute(whatTC, v2, sw, elt)
00401                     if debug and what is not whatTC:
00402                         self.logger.debug('substitute derived type: %s' %
00403                                           what.__class__)
00404                         
00405                     what.serialize(elem, sw, v2, **kw)
00406 #                    try:
00407 #                        what.serialize(elem, sw, v2, **kw)
00408 #                    except Exception, e:
00409 #                        raise EvaluateException('Serializing %s.%s, %s %s' %
00410 #                            (n, whatTC.aname or '?', e.__class__.__name__, str(e)))
00411 
00412                 if occurs < whatTC.minOccurs:
00413                     raise EvaluateException(\
00414                         'occurances(%d) less than minOccurs(%d) for <%s>' %
00415                         (occurs, whatTC.minOccurs, what.pname), sw.Backtrace(elt))
00416                     
00417                 continue
00418 
00419             if v is not None or what.nillable is True:
00420                 what = _get_type_or_substitute(whatTC, v, sw, elt)
00421                 if debug and what is not whatTC:
00422                     self.logger.debug('substitute derived type: %s' %
00423                                       what.__class__)
00424                 what.serialize(elem, sw, v, **kw)
00425 #                try:
00426 #                    what.serialize(elem, sw, v, **kw)
00427 #                except (ParseException, EvaluateException), e:
00428 #                    raise
00429 #                except Exception, e:
00430 #                    raise EvaluateException('Serializing %s.%s, %s %s' %
00431 #                        (n, whatTC.aname or '?', e.__class__.__name__, str(e)),
00432 #                        sw.Backtrace(elt))
00433                 continue
00434 
00435             raise EvaluateException('Got None for nillable(%s), minOccurs(%d) element (%s,%s), %s' %
00436                     (what.nillable, what.minOccurs, what.nspname, what.pname, elem),
00437                     sw.Backtrace(elt))
00438 
00439 
00440     def setDerivedTypeContents(self, extensions=None, restrictions=None):
00441         """For derived types set appropriate parameter and 
00442         """
00443         if extensions:
00444             ofwhat = list(self.ofwhat)
00445             if type(extensions) in _seqtypes:
00446                 ofwhat += list(extensions)
00447             else:
00448                 ofwhat.append(extensions)
00449         elif restrictions:
00450             if type(restrictions) in _seqtypes:
00451                 ofwhat = restrictions
00452             else:
00453                 ofwhat = (restrictions,)
00454         else:
00455             return
00456         self.ofwhat = tuple(ofwhat)
00457         self.lenofwhat = len(self.ofwhat)
00458 
00459 
00460 class Struct(ComplexType):
00461     '''Struct is a complex type for accessors identified by name. 
00462        Constraint: No element may have the same name as any other,
00463        nor may any element have a maxOccurs > 1.
00464        
00465       <xs:group name="Struct" >
00466         <xs:sequence>
00467           <xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
00468         </xs:sequence>
00469       </xs:group>
00470 
00471       <xs:complexType name="Struct" >
00472         <xs:group ref="tns:Struct" minOccurs="0" />
00473         <xs:attributeGroup ref="tns:commonAttributes"/>
00474       </xs:complexType> 
00475     '''
00476     logger = _GetLogger('ZSI.TCcompound.Struct')
00477     
00478     def __init__(self, pyclass, ofwhat, pname=None, inorder=False, inline=False,
00479         mutable=True, **kw):
00480         '''pyclass -- the Python class to hold the fields
00481         ofwhat -- a list of fields to be in the struct
00482         inorder -- fields must be in exact order or not
00483         inline -- don't href/id when serializing
00484         mutable -- object could change between multiple serializations
00485         '''
00486         ComplexType.__init__(self, pyclass, ofwhat, pname=pname, 
00487             inorder=inorder, inline=inline, mutable=mutable, 
00488             **kw
00489             )
00490         
00491         # Check Constraints
00492         whats = map(lambda what: (what.nspname,what.pname), self.ofwhat)
00493         for idx in range(len(self.ofwhat)):
00494             what = self.ofwhat[idx]
00495             key = (what.nspname,what.pname)
00496             if not isinstance(what, AnyElement) and what.maxOccurs > 1:
00497                 raise TypeError,\
00498                     'Constraint: no element can have a maxOccurs>1'
00499             if key in whats[idx+1:]:
00500                 raise TypeError,\
00501                     'Constraint: No element may have the same name as any other'
00502 
00503 
00504 class Array(TypeCode):
00505     '''An array.
00506         atype -- arrayType, (namespace,ncname) 
00507         mutable -- object could change between multiple serializations
00508         undeclared -- do not serialize/parse arrayType attribute.
00509     '''
00510     logger = _GetLogger('ZSI.TCcompound.Array')
00511     
00512     def __init__(self, atype, ofwhat, pname=None, dimensions=1, fill=None,
00513     sparse=False, mutable=False, size=None, nooffset=0, undeclared=False,
00514     childnames=None, **kw):
00515         TypeCode.__init__(self, pname, **kw)
00516         self.dimensions = dimensions
00517         self.atype = atype
00518         if undeclared is False and self.atype[1].endswith(']') is False:
00519             self.atype = (self.atype[0], '%s[]' %self.atype[1])
00520         # Support multiple dimensions
00521         if self.dimensions != 1:
00522             raise TypeError("Only single-dimensioned arrays supported")
00523         self.fill = fill
00524         self.sparse = sparse
00525         #if self.sparse: ofwhat.minOccurs = 0
00526         self.mutable = mutable
00527         self.size = size
00528         self.nooffset = nooffset
00529         self.undeclared = undeclared
00530         self.childnames = childnames
00531         if self.size:
00532             t = type(self.size)
00533             if t in _inttypes:
00534                 self.size = (self.size,)
00535             elif t in _seqtypes:
00536                 self.size = tuple(self.size)
00537             elif TypeCode.typechecks:
00538                 raise TypeError('Size must be integer or list, not ' + str(t))
00539 
00540         # by default use Any
00541         ofwhat = ofwhat or Any()
00542 
00543         if TypeCode.typechecks:
00544             if self.undeclared is False and type(atype) not in _seqtypes and len(atype) == 2:
00545                 raise TypeError("Array type must be a sequence of len 2.")
00546             t = type(ofwhat)
00547             if not isinstance(ofwhat, TypeCode):
00548                 raise TypeError(
00549                     'Array ofwhat outside the TypeCode hierarchy, ' +
00550                     str(ofwhat.__class__))
00551             if self.size:
00552                 if len(self.size) != self.dimensions:
00553                     raise TypeError('Array dimension/size mismatch')
00554                 for s in self.size:
00555                     if type(s) not in _inttypes:
00556                         raise TypeError('Array size "' + str(s) +
00557                                 '" is not an integer.')
00558         self.ofwhat = ofwhat
00559 
00560     def parse_offset(self, elt, ps):
00561         o = _find_arrayoffset(elt)
00562         if not o: return 0
00563         if not _offset_pat.match(o):
00564             raise EvaluateException('Bad offset "' + o + '"',
00565                         ps.Backtrace(elt))
00566         return int(o[1:-1])
00567 
00568     def parse_position(self, elt, ps):
00569         o = _find_arrayposition(elt)
00570         if not o: return None
00571         if o.find(',') > -1:
00572             raise EvaluateException('Sorry, no multi-dimensional arrays',
00573                     ps.Backtrace(elt))
00574         if not _position_pat.match(o):
00575             raise EvaluateException('Bad array position "' + o + '"',
00576                     ps.Backtrace(elt))
00577         return int(o[1:-1])
00578 
00579     def parse(self, elt, ps):
00580         href = _find_href(elt)
00581         if href:
00582             if _children(elt):
00583                 raise EvaluateException('Array has content and HREF',
00584                         ps.Backtrace(elt))
00585             elt = ps.FindLocalHREF(href, elt)
00586         if self.nilled(elt, ps): return Nilled
00587         if not _find_arraytype(elt) and self.undeclared is False:
00588             raise EvaluateException('Array expected', ps.Backtrace(elt))
00589         t = _find_type(elt)
00590         if t:
00591             pass # XXX should check the type, but parsing that is hairy.
00592         offset = self.parse_offset(elt, ps)
00593         v, vlen = [], 0
00594         if offset and not self.sparse:
00595             while vlen < offset:
00596                 vlen += 1
00597                 v.append(self.fill)
00598         for c in _child_elements(elt):
00599             item = self.ofwhat.parse(c, ps)
00600             position = self.parse_position(c, ps) or offset
00601             if self.sparse:
00602                 v.append((position, item))
00603             else:
00604                 while offset < position:
00605                     offset += 1
00606                     v.append(self.fill)
00607                 v.append(item)
00608             offset += 1
00609         return v
00610 
00611     def serialize(self, elt, sw, pyobj, name=None, childnames=None, **kw):
00612         debug = self.logger.debugOn()
00613         if debug:
00614             self.logger.debug("serialize: %r" %pyobj)
00615         
00616         if self.mutable is False and sw.Known(pyobj): return
00617         objid = _get_idstr(pyobj)
00618         ns,n = self.get_name(name, objid)
00619         el = elt.createAppendElement(ns, n)
00620 
00621         # nillable
00622         if self.nillable is True and pyobj is None:
00623             self.serialize_as_nil(el)
00624             return None
00625 
00626         # other attributes
00627         self.set_attributes(el, pyobj)
00628 
00629         # soap href attribute
00630         unique = self.unique or kw.get('unique', False)
00631         if unique is False and sw.Known(pyobj):
00632             self.set_attribute_href(el, objid)
00633             return None
00634 
00635         # xsi:type attribute 
00636         if kw.get('typed', self.typed) is True:
00637             self.set_attribute_xsi_type(el, **kw)
00638 
00639         # soap id attribute
00640         if self.unique is False:
00641             self.set_attribute_id(el, objid)
00642 
00643         offset = 0
00644         if self.sparse is False and self.nooffset is False:
00645             offset, end = 0, len(pyobj)
00646             while offset < end and pyobj[offset] == self.fill:
00647                 offset += 1
00648             if offset: 
00649                 el.setAttributeNS(SOAP.ENC, 'offset', '[%d]' %offset)
00650 
00651         if self.undeclared is False:
00652             el.setAttributeNS(SOAP.ENC, 'arrayType', 
00653                 '%s:%s' %(el.getPrefix(self.atype[0]), self.atype[1])
00654             )
00655 
00656         if debug:
00657             self.logger.debug("ofwhat: %r" %self.ofwhat)
00658 
00659         d = {}
00660         kn = childnames or self.childnames
00661         if kn:
00662             d['name'] = kn
00663         elif not self.ofwhat.aname:
00664             d['name'] = 'element'
00665             
00666         if self.sparse is False:
00667             for e in pyobj[offset:]: self.ofwhat.serialize(el, sw, e, **d)
00668         else:
00669             position = 0
00670             for pos, v in pyobj:
00671                 if pos != position:
00672                     el.setAttributeNS(SOAP.ENC, 'position', '[%d]' %pos)
00673                     position = pos
00674 
00675                 self.ofwhat.serialize(el, sw, v, **d)
00676                 position += 1
00677 
00678 
00679 if __name__ == '__main__': print _copyright

Generated on Wed Oct 20 2010 11:12:16 for APBS by  doxygen 1.7.2