Module EDGenerateDS
[hide private]
[frames] | no frames]

Source Code for Module EDGenerateDS

   1  #!/usr/bin/env python 
   2  # 
   3  # This file has been modified to meet certain requirements for the EDNA project. 
   4  # Please see below the original copy right message for generateDS.py. 
   5  # 
   6   
   7  """ 
   8  1. Synopsis: 
   9   
  10  Generate Python classes from XML Schema definition. 
  11  Input is read from in_xsd_file or, if "-" (dash) arg, from stdin. 
  12  Output is written to files named in "-o" and "-s" options. 
  13       
  14  2. Usage: 
  15   
  16  python EDGenerateDS.py [ options ] <xsd_file> 
  17  python EDGenerateDS.py [ options ] - 
  18   
  19  3. Options: 
  20   
  21  -h, --help               Display this help information. 
  22  -o <outfilename>         Output file name for data representation classes 
  23  -s <subclassfilename>    Output file name for subclasses 
  24  -p <prefix>              Prefix string to be pre-pended to the class names 
  25  -f                       Force creation of output files.  Do not ask. 
  26  -a <namespaceabbrev>     Namespace abbreviation, e.g. "xsd:". Default = 'xs:'.                          
  27  -b <behaviorfilename>    Input file name for behaviors added to subclasses 
  28  -m                       Generate properties for member variables 
  29  --subclass-suffix="XXX"  Append XXX to the generated subclass names. Default="Sub".                          
  30  --root-element="XXX"     Assume XXX is root element of instance docs.Default is first element defined in schema.                          
  31  --super="XXX"            Super module name in subclass module. Default="???" 
  32  --validator-bodies=path  Path to a directory containing files that provide bodies (implementations) of validator methods.                          
  33  --use-old-getter-setter  Name getters and setters getVar() and setVar(), instead of get_var() and set_var().                          
  34  --user-methods= <module>, 
  35  -u <module               Optional module containing user methods.  See section "User Methods" in the documentation. 
  36                            
  37  """ 
  38   
  39   
  40  ## LICENSE 
  41   
  42  ## Copyright (c) 2003 Dave Kuhlman 
  43   
  44  ## Permission is hereby granted, free of charge, to any person obtaining 
  45  ## a copy of this software and associated documentation files (the 
  46  ## "Software"), to deal in the Software without restriction, including 
  47  ## without limitation the rights to use, copy, modify, merge, publish, 
  48  ## distribute, sublicense, and/or sell copies of the Software, and to 
  49  ## permit persons to whom the Software is furnished to do so, subject to 
  50  ## the following conditions: 
  51   
  52  ## The above copyright notice and this permission notice shall be 
  53  ## included in all copies or substantial portions of the Software. 
  54   
  55  ## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
  56  ## EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
  57  ## MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
  58  ## IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 
  59  ## CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
  60  ## TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
  61  ## SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
  62   
  63   
  64   
  65  #from __future__ import generators   # only needed for Python 2.2 
  66   
  67  import sys 
  68  import os.path 
  69  import time 
  70  import getopt 
  71  import urllib2 
  72  from xml.sax import handler, make_parser 
  73  import xml.sax.xmlreader 
  74  import logging 
  75  import keyword 
  76   
  77  # Default logger configuration 
  78  #logging.basicConfig(level=logging.DEBUG, 
  79  #                    format='%(asctime)s %(levelname)s %(message)s') 
  80   
  81  ##from IPython.Shell import IPShellEmbed 
  82  ##args = '' 
  83  ##ipshell = IPShellEmbed(args, 
  84  ##    banner = 'Dropping into IPython', 
  85  ##    exit_msg = 'Leaving Interpreter, back to program.') 
  86   
  87  # Then use the following line where and when you want to drop into the 
  88  # IPython shell: 
  89  #    ipshell('<some message> -- Entering ipshell.\\nHit Ctrl-D to exit') 
  90   
  91   
  92  # 
  93  # Global variables etc. 
  94  # 
  95  GenerateProperties = 0 
  96  UseOldGetterSetter = 0 
  97  DelayedElements = [] 
  98  DelayedElements_subclass = [] 
  99  AlreadyGenerated = [] 
 100  AlreadyGenerated_subclass = [] 
 101  PostponedExtensions = [] 
 102  ElementsForSubclasses = [] 
 103  ElementDict = {} 
 104  SaxElementDict = {} 
 105  Force = 0 
 106   
 107  ##NameTable = { 
 108  ##    'class': 'klass', 
 109  ##    'import': 'emport', 
 110  ##    'type': 'ttype', 
 111  ##    'pass': 'ppass', 
 112  ##    } 
 113   
 114  NameTable = { 
 115      'type': 'typexx', 
 116      } 
 117  for kw in keyword.kwlist: 
 118      NameTable[kw] = '%sxx' % kw 
 119   
 120   
 121  SubclassSuffix = 'Sub' 
 122  RootElement = None 
 123  AttributeGroups = {} 
 124  SubstitutionGroups = {} 
 125  # 
 126  # SubstitutionGroups can also include simple types that are 
 127  #   not (defined) elements.  Keep a list of these simple types. 
 128  #   These are simple types defined at top level. 
 129  SimpleElementDict = {} 
 130  SimpleTypeDict = {} 
 131  ValidatorBodiesBasePath = None 
 132  UserMethodsPath = None 
 133  UserMethodsModule = None 
 134  XsdNameSpace = '' 
 135   
136 -def set_type_constants(nameSpace):
137 global StringType, TokenType, \ 138 IntegerType, DecimalType, \ 139 ShortType, LongType, \ 140 PositiveIntegerType, NegativeIntegerType, \ 141 NonPositiveIntegerType, NonNegativeIntegerType, \ 142 BooleanType, FloatType, DoubleType, \ 143 ElementType, ComplexTypeType, SequenceType, ChoiceType, \ 144 AttributeGroupType, AttributeType, SchemaType, \ 145 DateTimeType, DateType, \ 146 ComplexContentType, ExtensionType, \ 147 IDType, IDREFType, IDREFSType, IDTypes, \ 148 NameType, NCNameType, QNameType, NameTypes, \ 149 AnyAttributeType, SimpleTypeType, RestrictionType, \ 150 WhiteSpaceType, ListType, EnumerationType, UnionType, \ 151 OtherSimpleTypes 152 AttributeGroupType = nameSpace + 'attributeGroup' 153 AttributeType = nameSpace + 'attribute' 154 BooleanType = nameSpace + 'boolean' 155 ChoiceType = nameSpace + 'choice' 156 ComplexContentType = nameSpace + 'complexContent' 157 ComplexTypeType = nameSpace + 'complexType' 158 SimpleTypeType = nameSpace + 'simpleType' 159 RestrictionType = nameSpace + 'restriction' 160 WhiteSpaceType = nameSpace + 'whiteSpace' 161 AnyAttributeType = nameSpace + 'anyAttribute' 162 DateTimeType = nameSpace + 'dateTime' 163 DateType = nameSpace + 'date' 164 IntegerType = (nameSpace + 'integer', 165 nameSpace + 'unsignedShort', 166 nameSpace + 'short', 167 nameSpace + 'long', 168 nameSpace + 'int', 169 nameSpace + 'short', 170 ) 171 #ShortType = nameSpace + 'short' 172 #LongType = nameSpace + 'long' 173 DecimalType = nameSpace + 'decimal' 174 PositiveIntegerType = nameSpace + 'positiveInteger' 175 NegativeIntegerType = nameSpace + 'negativeInteger' 176 NonPositiveIntegerType = nameSpace + 'nonPositiveInteger' 177 NonNegativeIntegerType = nameSpace + 'nonNegativeInteger' 178 DoubleType = nameSpace + 'double' 179 ElementType = nameSpace + 'element' 180 ExtensionType = nameSpace + 'extension' 181 FloatType = nameSpace + 'float' 182 IDREFSType = nameSpace + 'IDREFS' 183 IDREFType = nameSpace + 'IDREF' 184 IDType = nameSpace + 'ID' 185 IDTypes = (IDREFSType, IDREFType, IDType,) 186 SchemaType = nameSpace + 'schema' 187 SequenceType = nameSpace + 'sequence' 188 StringType = (nameSpace + 'string', 189 nameSpace + 'duration', 190 nameSpace + 'anyURI', 191 nameSpace + 'normalizedString', 192 ) 193 TokenType = nameSpace + 'token' 194 NameType = nameSpace + 'Name' 195 NCNameType = nameSpace + 'NCName' 196 QNameType = nameSpace + 'QName' 197 NameTypes = (NameType, NCNameType, QNameType,) 198 ListType = nameSpace + 'list' 199 EnumerationType = nameSpace + 'enumeration' 200 UnionType = nameSpace + 'union' 201 OtherSimpleTypes = ( 202 nameSpace + 'ENTITIES', 203 nameSpace + 'ENTITY', 204 nameSpace + 'ID', 205 nameSpace + 'IDREF', 206 nameSpace + 'IDREFS', 207 nameSpace + 'NCName', 208 nameSpace + 'NMTOKEN', 209 nameSpace + 'NMTOKENS', 210 nameSpace + 'NOTATION', 211 nameSpace + 'Name', 212 nameSpace + 'QName', 213 nameSpace + 'anyURI', 214 nameSpace + 'base64Binary', 215 nameSpace + 'boolean', 216 nameSpace + 'byte', 217 nameSpace + 'date', 218 nameSpace + 'dateTime', 219 nameSpace + 'decimal', 220 nameSpace + 'double', 221 nameSpace + 'duration', 222 nameSpace + 'float', 223 nameSpace + 'gDay', 224 nameSpace + 'gMonth', 225 nameSpace + 'gMonthDay', 226 nameSpace + 'gYear', 227 nameSpace + 'gYearMonth', 228 nameSpace + 'hexBinary', 229 nameSpace + 'int', 230 nameSpace + 'integer', 231 nameSpace + 'language', 232 nameSpace + 'long', 233 nameSpace + 'negativeInteger', 234 nameSpace + 'nonNegativeInteger', 235 nameSpace + 'nonPositiveInteger', 236 nameSpace + 'normalizedString', 237 nameSpace + 'positiveInteger', 238 nameSpace + 'short', 239 nameSpace + 'string', 240 nameSpace + 'time', 241 nameSpace + 'token', 242 nameSpace + 'unsignedByte', 243 nameSpace + 'unsignedInt', 244 nameSpace + 'unsignedLong', 245 nameSpace + 'unsignedShort', 246 )
247 248 249 250 # 251 # For debugging. 252 # 253 254 # Print only if DEBUG is true. 255 DEBUG = 0
256 -def dbgprint(level, msg):
257 if DEBUG and level > 0: 258 print msg
259
260 -def pplist(lst):
261 for count, item in enumerate(lst): 262 print '%d. %s' % (count, item)
263 264 265 266 # 267 # Representation of element definition. 268 # 269
270 -def showLevel(outfile, level):
271 for idx in range(level): 272 outfile.write(' ')
273 274
275 -class XschemaElementBase:
276 - def __init__(self):
277 pass
278 279
280 -class SimpleTypeElement(XschemaElementBase):
281 - def __init__(self, name):
282 XschemaElementBase.__init__(self) 283 self.name = name 284 self.base = None 285 self.collapseWhiteSpace = 0 286 # Attribute definitions for the current attributeGroup, if there is one. 287 self.attributeGroup = None 288 # Attribute definitions for the currect element. 289 self.attributeDefs = {} 290 self.complexType = 0 291 # Enumeration values for the current element. 292 self.values = list() 293 # The other simple types this is a union of. 294 self.unionOf = list()
295 - def setName(self, name): self.name = name
296 - def getName(self): return self.name
297 - def setBase(self, base): self.base = base
298 - def getBase(self): return self.base
299 - def setSimpleType(self, simpleType): self.simpleType = simpleType
300 - def getSimpleType(self): return self.simpleType
301 - def getAttributeGroups(self): return self.attributeGroups
302 - def setAttributeGroup(self, attributeGroup): self.attributeGroup = attributeGroup
303 - def getAttributeGroup(self): return self.attributeGroup
304 - def __str__(self):
305 s1 = '<"%s" SimpleTypeElement instance at 0x%x>' % \ 306 (self.getName(), id(self)) 307 return s1
308
309 - def __repr__(self):
310 s1 = '<"%s" SimpleTypeElement instance at 0x%x>' % \ 311 (self.getName(), id(self)) 312 return s1
313 314
315 -class XschemaElement(XschemaElementBase):
316 - def __init__(self, attrs):
317 XschemaElementBase.__init__(self) 318 self.cleanName = '' 319 self.attrs = dict(attrs) 320 name_val = '' 321 type_val = '' 322 ref_val = '' 323 if 'name' in self.attrs: 324 name_val = strip_namespace(self.attrs['name']) 325 if 'type' in self.attrs: 326 if self.attrs['type'].startswith(XsdNameSpace): 327 type_val = self.attrs['type'] 328 else: 329 type_val = strip_namespace(self.attrs['type']) 330 if 'ref' in self.attrs: 331 ref_val = strip_namespace(self.attrs['ref']) 332 if type_val and not name_val: 333 name_val = type_val 334 if ref_val and not name_val: 335 name_val = ref_val 336 if ref_val and not type_val: 337 type_val = ref_val 338 if name_val: 339 self.attrs['name'] = name_val 340 if type_val: 341 self.attrs['type'] = type_val 342 if ref_val: 343 self.attrs['ref'] = ref_val 344 self.name = name_val 345 #import pdb; pdb.set_trace() 346 self.children = [] 347 self.optional = False 348 self.minOccurs = 1 349 self.maxOccurs = 1 350 self.complex = 0 351 self.complexType = 0 352 self.type = 'NoneType' 353 self.mixed = 0 354 self.base = None 355 self.mixedExtensionError = 0 356 self.collapseWhiteSpace = 0 357 # Attribute definitions for the currect element. 358 self.attributeDefs = {} 359 # Attribute definitions for the current attributeGroup, if there is one. 360 self.attributeGroup = None 361 # List of names of attributes for this element. 362 # We will add the attribute defintions in each of these groups 363 # to this element in annotate(). 364 self.attributeGroupNameList = [] 365 self.topLevel = 0 366 # Does this element contain an anyAttribute? 367 self.anyAttribute = 0 368 self.explicit_define = 0 369 self.simpleType = None 370 # Enumeration values for the current element. 371 self.values = list() 372 # The parent choice for the current element. 373 self.choice = None
374
375 - def addChild(self, element):
376 self.children.append(element)
377 - def getChildren(self): return self.children
378 - def getName(self): return self.name
379 - def getCleanName(self): return self.cleanName
380 - def getUnmappedCleanName(self): return self.unmappedCleanName
381 - def setName(self, name): self.name = name
382 - def getAttrs(self): return self.attrs
383 - def setAttrs(self, attrs): self.attrs = attrs
384 - def getMinOccurs(self): return self.minOccurs
385 - def getMaxOccurs(self): return self.maxOccurs
386 - def getOptional(self): return self.optional
387 - def getRawType(self): return self.type
388 - def setExplicitDefine(self, explicit_define):
389 self.explicit_define = explicit_define
390 - def isExplicitDefine(self): return self.explicit_define
391 - def getType(self):
392 returnType = self.type 393 if ElementDict.has_key(self.type): 394 typeObj = ElementDict[self.type] 395 typeObjType = typeObj.getRawType() 396 if typeObjType in StringType or \ 397 typeObjType == TokenType or \ 398 typeObjType == DateTimeType or \ 399 typeObjType == DateType or \ 400 typeObjType in IntegerType or \ 401 typeObjType == DecimalType or \ 402 typeObjType == PositiveIntegerType or \ 403 typeObjType == NegativeIntegerType or \ 404 typeObjType == NonPositiveIntegerType or \ 405 typeObjType == NonNegativeIntegerType or \ 406 typeObjType == BooleanType or \ 407 typeObjType == FloatType or \ 408 typeObjType == DoubleType: 409 returnType = typeObjType 410 return returnType
411 - def isComplex(self): return self.complex
412 - def addAttributeDefs(self, attrs): self.attributeDefs.append(attrs)
413 - def getAttributeDefs(self): return self.attributeDefs
414 - def isMixed(self): return self.mixed
415 - def setMixed(self, mixed): self.mixed = mixed
416 - def setBase(self, base): self.base = base
417 - def getBase(self): return self.base
418 - def getMixedExtensionError(self): return self.mixedExtensionError
419 - def getAttributeGroups(self): return self.attributeGroups
420 - def addAttribute(self, name, attribute):
421 self.attributeGroups[name] = attribute
422 - def setAttributeGroup(self, attributeGroup): self.attributeGroup = attributeGroup
423 - def getAttributeGroup(self): return self.attributeGroup
424 - def setTopLevel(self, topLevel): self.topLevel = topLevel
425 - def getTopLevel(self): return self.topLevel
426 - def setAnyAttribute(self, anyAttribute): self.anyAttribute = anyAttribute
427 - def getAnyAttribute(self): return self.anyAttribute
428 - def setSimpleType(self, simpleType): self.simpleType = simpleType
429 - def getSimpleType(self): return self.simpleType
430
431 - def show(self, outfile, level):
432 showLevel(outfile, level) 433 outfile.write('Name: %s Type: %s\n' % (self.name, self.getType())) 434 showLevel(outfile, level) 435 outfile.write(' - Complex: %d MaxOccurs: %d MinOccurs: %d\n' % \ 436 (self.complex, self.maxOccurs, self.minOccurs)) 437 showLevel(outfile, level) 438 outfile.write(' - Attrs: %s\n' % self.attrs) 439 showLevel(outfile, level) 440 outfile.write(' - AttributeDefs: %s\n' % self.attributeDefs) 441 442 for attr in self.getAttributeDefs(): 443 key = attr['name'] 444 try: 445 value = attr['value'] 446 except Exception: 447 value = '<empty>' 448 showLevel(outfile, level + 1) 449 outfile.write('key: %s value: %s\n' % \ 450 (key, value)) 451 for child in self.children: 452 child.show(outfile, level + 1)
453
454 - def annotate(self):
455 self.collect_element_dict() 456 self.annotate_find_type() 457 self.annotate_tree() 458 self.fix_dup_names() 459 self.coerce_attr_types() 460 self.checkMixedBases()
461
462 - def collect_element_dict(self):
463 base = self.getBase() 464 if self.getTopLevel() or len(self.getChildren()) > 0 or \ 465 len(self.getAttributeDefs()) > 0 or base: 466 ElementDict[self.name] = self 467 for child in self.children: 468 child.collect_element_dict()
469
470 - def element_is_complex(self):
471 pass
472 473 # If it is a mixed-content element and it is defined as 474 # an extension, then all of its bases (base, base of base, ...) 475 # must be mixed-content. Mark it as an error, if not.
476 - def checkMixedBases(self):
477 self.checkMixedBasesChain(self, self.mixed) 478 for child in self.children: 479 child.checkMixedBases()
480
481 - def checkMixedBasesChain(self, child, childMixed):
482 base = self.getBase() 483 if base and base in ElementDict: 484 parent = ElementDict[base] 485 if childMixed != parent.isMixed(): 486 self.mixedExtensionError = 1 487 return 488 parent.checkMixedBasesChain(child, childMixed)
489
490 - def resolve_type(self):
491 self.complex = 0 492 # If it has any attributes, then it's complex. 493 attrDefs = self.getAttributeDefs() 494 if len(attrDefs) > 0: 495 self.complex = 1 496 # type_val = '' 497 type_val = self.resolve_type_1() 498 if type_val: 499 if type_val in ElementDict: 500 type_val1 = type_val 501 # The following loop handles the case where an Element's 502 # reference element has no sub-elements and whose type is 503 # another simpleType (potentially of the same name). Its 504 # fundamental function is to avoid the incorrect 505 # categorization of "complex" to Elements which are not and 506 # correctly resolve the Element's type. It also handles cases 507 # where the Element's "simpleType" is so-called "top level" 508 # and is only available through the global SimpleTypeDict. 509 i = 0 510 while True: 511 element = ElementDict[type_val1] 512 t = element.resolve_type_1() 513 # If the type is available in the SimpleTypeDict, we 514 # know we've gone far enough in the Element hierarchy 515 # and can return the correct base type. 516 if t in SimpleTypeDict: 517 type_val1 = SimpleTypeDict[t].getBase() 518 break 519 # If the type name is the same as the previous type name 520 # then we know we've fully resolved the Element hierarchy 521 # and the Element is well and truely "complex". There is 522 # also a need to handle cases where the Element name and 523 # its type name are the same (ie. this is our first time 524 # through the loop). For example: 525 # <xsd:element name="ReallyCool" type="ReallyCool"/> 526 # <xsd:simpleType name="ReallyCool"> 527 # <xsd:restriction base="xsd:string"> 528 # <xsd:enumeration value="MyThing"/> 529 # </xsd:restriction> 530 # </xsd:simpleType> 531 if t == type_val1 and i != 0: 532 break 533 if t not in ElementDict: 534 type_val1 = t 535 break 536 type_val1 = t 537 i += 1 538 if type_val1 in StringType or \ 539 type_val1 == TokenType or \ 540 type_val1 == DateTimeType or \ 541 type_val1 == DateType or \ 542 type_val1 in IntegerType or \ 543 type_val1 == DecimalType or \ 544 type_val1 == PositiveIntegerType or \ 545 type_val1 == NonPositiveIntegerType or \ 546 type_val1 == NegativeIntegerType or \ 547 type_val1 == NonNegativeIntegerType or \ 548 type_val1 == BooleanType or \ 549 type_val1 == FloatType or \ 550 type_val1 == DoubleType: 551 type_val = type_val1 552 else: 553 self.complex = 1 554 else: 555 if type_val in StringType or \ 556 type_val == TokenType or \ 557 type_val == DateTimeType or \ 558 type_val == DateType or \ 559 type_val in IntegerType or \ 560 type_val == DecimalType or \ 561 type_val == PositiveIntegerType or \ 562 type_val == NonPositiveIntegerType or \ 563 type_val == NegativeIntegerType or \ 564 type_val == NonNegativeIntegerType or \ 565 type_val == BooleanType or \ 566 type_val == FloatType or \ 567 type_val == DoubleType: 568 pass 569 else: 570 type_val = StringType[0] 571 else: 572 type_val = StringType[0] 573 return type_val
574
575 - def resolve_type_1(self):
576 type_val = '' 577 if 'type' in self.attrs: 578 # fix 579 #type_val = strip_namespace(self.attrs['type']) 580 type_val = self.attrs['type'] 581 if type_val in SimpleTypeDict: 582 self.simpleType = type_val 583 elif 'ref' in self.attrs: 584 # fix 585 type_val = strip_namespace(self.attrs['ref']) 586 #type_val = self.attrs['ref'] 587 elif 'name' in self.attrs: 588 # fix 589 type_val = strip_namespace(self.attrs['name']) 590 #type_val = self.attrs['name'] 591 return type_val
592
593 - def annotate_find_type(self):
594 type_val = self.resolve_type() 595 self.attrs['type'] = type_val 596 self.type = type_val 597 if not self.complex: 598 SimpleElementDict[self.name] = self.name 599 for child in self.children: 600 child.annotate_find_type()
601
602 - def annotate_tree(self):
603 # If there is a namespace, replace it with an underscore. 604 if self.base: 605 self.base = strip_namespace(self.base) 606 self.unmappedCleanName = cleanupName(self.name) 607 self.cleanName = mapName(self.unmappedCleanName) 608 SaxElementDict[self.cleanName] = self 609 self.replace_attributeGroup_names() 610 611 # Resolve "maxOccurs" attribute 612 if 'maxOccurs' in self.attrs.keys(): 613 maxOccurs = self.attrs['maxOccurs'] 614 elif self.choice and 'maxOccurs' in self.choice.attrs.keys(): 615 maxOccurs = self.choice.attrs['maxOccurs'] 616 else: 617 maxOccurs = 1 618 619 # Resolve "minOccurs" attribute 620 if 'minOccurs' in self.attrs.keys(): 621 minOccurs = self.attrs['minOccurs'] 622 elif self.choice and 'minOccurs' in self.choice.attrs.keys(): 623 minOccurs = self.choice.attrs['minOccurs'] 624 else: 625 minOccurs = 1 626 627 # Cleanup "minOccurs" and "maxOccurs" attributes 628 try: 629 minOccurs = int(minOccurs) 630 if minOccurs == 0: 631 self.optional = True 632 except ValueError: 633 sys.stderr.write('*** %s minOccurs must be integer.' % \ 634 self.getName()) 635 sys.exit(-1) 636 try: 637 if maxOccurs == 'unbounded': 638 maxOccurs = 99999 639 else: 640 maxOccurs = int(maxOccurs) 641 except ValueError: 642 sys.stderr.write('*** %s maxOccurs must be integer or "unbounded".' % \ 643 self.getName()) 644 sys.exit(-1) 645 self.minOccurs = minOccurs 646 self.maxOccurs = maxOccurs 647 648 # If it does not have a type, then make the type the same as the name. 649 if self.type == 'NoneType' and self.name: 650 self.type = self.name 651 # Is it a mixed-content element definition? 652 if 'mixed' in self.attrs.keys(): 653 mixed = self.attrs['mixed'].strip() 654 if mixed == '1' or mixed.lower() == 'true': 655 self.mixed = 1 656 # If this element has a base and the base is a simple type and 657 # the simple type is collapseWhiteSpace, then mark this 658 # element as collapseWhiteSpace. 659 base = self.getBase() 660 if base and base in SimpleTypeDict: 661 parent = SimpleTypeDict[base] 662 if isinstance(parent, SimpleTypeElement) and \ 663 parent.collapseWhiteSpace: 664 self.collapseWhiteSpace = 1 665 #ipshell('Annotating collapseWhiteSpace -- Entering ipshell.\\nHit Ctrl-D to exit') 666 # Do it recursively for all descendents. 667 for child in self.children: 668 child.annotate_tree()
669 670 # 671 # For each name in the attributeGroupNameList for this element, 672 # add the attributes defined for that name in the global 673 # attributeGroup dictionary.
675 for groupName in self.attributeGroupNameList: 676 if AttributeGroups.has_key(groupName): 677 attrGroup = AttributeGroups[groupName] 678 for name in attrGroup.getKeys(): 679 attr = attrGroup.get(name) 680 self.attributeDefs[name] = attr 681 else: 682 print '*** Error. attributeGroup %s not defined.' % groupName
683
684 - def __str__(self):
685 s1 = '<"%s" XschemaElement instance at 0x%x>' % \ 686 (self.getName(), id(self)) 687 return s1
688
689 - def __repr__(self):
690 s1 = '<"%s" XschemaElement instance at 0x%x>' % \ 691 (self.getName(), id(self)) 692 return s1
693
694 - def fix_dup_names(self):
695 # Patch-up names that are used for both a child element and an attribute. 696 # 697 attrDefs = self.getAttributeDefs() 698 # Collect a list of child element names. 699 # Must do this for base (extension) elements also. 700 elementNames = [] 701 self.collectElementNames(elementNames) 702 replaced = [] 703 # Create the needed new attributes. 704 keys = attrDefs.keys() 705 for key in keys: 706 attr = attrDefs[key] 707 name = attr.getName() 708 if name in elementNames: 709 newName = name + '_attr' 710 newAttr = XschemaAttribute(newName) 711 attrDefs[newName] = newAttr 712 replaced.append(name) 713 # Remove the old (replaced) attributes. 714 for name in replaced: 715 del attrDefs[name] 716 for child in self.children: 717 child.fix_dup_names()
718
719 - def collectElementNames(self, elementNames):
720 for child in self.children: 721 elementNames.append(cleanupName(child.cleanName)) 722 base = self.getBase() 723 if base and base in ElementDict: 724 parent = ElementDict[base] 725 parent.collectElementNames(elementNames)
726
727 - def coerce_attr_types(self):
728 replacements = [] 729 attrDefs = self.getAttributeDefs() 730 for idx, name in enumerate(attrDefs): 731 attr = attrDefs[name] 732 attrType = attr.getData_type() 733 if attrType == IDType or \ 734 attrType == IDREFType or \ 735 attrType == IDREFSType: 736 attr.setData_type(StringType[0]) 737 for child in self.children: 738 child.coerce_attr_types()
739 # end class XschemaElement 740 741
742 -class XschemaAttributeGroup:
743 - def __init__(self, name='', group=None):
744 self.name = name 745 if group: 746 self.group = group 747 else: 748 self.group = {}
749 - def setName(self, name): self.name = name
750 - def getName(self): return self.name
751 - def setGroup(self, group): self.group = group
752 - def getGroup(self): return self.group
753 - def get(self, name, default=None):
754 if self.group.has_key(name): 755 return self.group[name] 756 else: 757 return default
758 - def getKeys(self):
759 return self.group.keys()
760 - def add(self, name, attr):
761 self.group[name] = attr
762 - def delete(self, name):
763 if has_key(self.group, name): 764 del self.group[name] 765 return 1 766 else: 767 return 0
768 # end class XschemaAttributeGroup 769
770 -class XschemaAttribute:
771 - def __init__(self, name, data_type='xs:string', use='optional'):
772 self.name = name 773 self.data_type = data_type 774 self.use = use 775 # Enumeration values for the attribute. 776 self.values = list()
777 - def setName(self, name): self.name = name
778 - def getName(self): return self.name
779 - def setData_type(self, data_type): self.data_type = data_type
780 - def getData_type(self): return self.data_type
781 - def setUse(self, use): self.use = use
782 - def getUse(self): return self.use
783 # end class XschemaAttribute 784 785 786 # 787 # SAX handler 788 #
789 -class XschemaHandler(handler.ContentHandler):
790 - def __init__(self):
791 handler.ContentHandler.__init__(self) 792 self.stack = [] 793 self.root = None 794 self.inElement = 0 795 self.inComplexType = 0 796 self.inNonanonymousComplexType = 0 797 self.inSequence = 0 798 self.inChoice = 1 799 self.inAttribute = 0 800 self.inAttributeGroup = 0 801 self.inSimpleType = 0 802 # The last attribute we processed. 803 self.lastAttribute = None 804 # Simple types that exist in the global context and may be used to 805 # qualify the type of many elements and/or attributes. 806 self.topLevelSimpleTypes = list() 807 # The current choice type we're in 808 self.currentChoice = None
809 ## self.dbgcount = 1 810 ## self.dbgnames = [] 811
812 - def getRoot(self):
813 return self.root
814
815 - def showError(self, msg):
816 print msg 817 sys.exit(-1)
818
819 - def startElement(self, name, attrs):
820 logging.debug("Start element: %s %s" % (name, repr(attrs.items()))) 821 822 if name == SchemaType: 823 self.inSchema = 1 824 element = XschemaElement(attrs) 825 if len(self.stack) == 1: 826 element.setTopLevel(1) 827 self.stack.append(element) 828 # If there is an attribute "xmlns" and its value is 829 # "http://www.w3.org/2001/XMLSchema", then remember and 830 # use that namespace prefix. 831 for name, value in attrs.items(): 832 if name[:6] == 'xmlns:' and \ 833 value == 'http://www.w3.org/2001/XMLSchema': 834 nameSpace = name[6:] + ':' 835 set_type_constants(nameSpace) 836 elif name == ElementType or ((name == ComplexTypeType) and (len(self.stack) == 1)): 837 self.inElement = 1 838 self.inNonanonymousComplexType = 1 839 element = XschemaElement(attrs) 840 if not 'type' in attrs.keys() and not 'ref' in attrs.keys(): 841 element.setExplicitDefine(1) 842 if len(self.stack) == 1: 843 element.setTopLevel(1) 844 if 'substitutionGroup' in attrs.keys() and 'name' in attrs.keys(): 845 substituteName = attrs['name'] 846 headName = attrs['substitutionGroup'] 847 if headName not in SubstitutionGroups: 848 SubstitutionGroups[headName] = [] 849 SubstitutionGroups[headName].append(substituteName) 850 if name == ComplexTypeType: 851 element.complexType = 1 852 if self.inChoice and self.currentChoice: 853 element.choice = self.currentChoice 854 self.stack.append(element) 855 elif name == ComplexTypeType: 856 # If it have any attributes and there is something on the stack, 857 # then copy the attributes to the item on top of the stack. 858 if len(self.stack) > 1 and len(attrs) > 0: 859 parentDict = self.stack[-1].getAttrs() 860 for key in attrs.keys(): 861 parentDict[key] = attrs[key] 862 self.inComplexType = 1 863 elif name == SequenceType: 864 self.inSequence = 1 865 elif name == ChoiceType: 866 self.currentChoice = XschemaElement(attrs) 867 self.inChoice = 1 868 elif name == AttributeType: 869 self.inAttribute = 1 870 if 'name' in attrs.keys(): 871 name = attrs['name'] 872 elif 'ref' in attrs.keys(): 873 name = strip_namespace(attrs['ref']) 874 else: 875 name = 'no_attribute_name' 876 if 'type' in attrs.keys(): 877 data_type = attrs['type'] 878 else: 879 data_type = StringType[0] 880 if 'use' in attrs.keys(): 881 use = attrs['use'] 882 else: 883 use = 'optional' 884 if self.stack[-1].attributeGroup: 885 # Add this attribute to a current attributeGroup. 886 attribute = XschemaAttribute(name, data_type, use) 887 self.stack[-1].attributeGroup.add(name, attribute) 888 else: 889 # Add this attribute to the element/complexType. 890 attribute = XschemaAttribute(name, data_type, use) 891 self.stack[-1].attributeDefs[name] = attribute 892 self.lastAttribute = attribute 893 elif name == AttributeGroupType: 894 self.inAttributeGroup = 1 895 # If it has attribute 'name', then it's a definition. 896 # Prepare to save it as an attributeGroup. 897 if 'name' in attrs.keys(): 898 name = strip_namespace(attrs['name']) 899 attributeGroup = XschemaAttributeGroup(name) 900 element = XschemaElement(attrs) 901 if len(self.stack) == 1: 902 element.setTopLevel(1) 903 element.setAttributeGroup(attributeGroup) 904 self.stack.append(element) 905 # If it has attribute 'ref', add it to the list of 906 # attributeGroups for this element/complexType. 907 if 'ref' in attrs.keys(): 908 self.stack[-1].attributeGroupNameList.append(attrs['ref']) 909 elif name == ComplexContentType: 910 pass 911 elif name == ExtensionType: 912 if 'base' in attrs.keys() and len(self.stack) > 0: 913 extensionBase = attrs['base'] 914 if extensionBase in StringType or \ 915 extensionBase in IDTypes or \ 916 extensionBase in NameTypes or \ 917 extensionBase == TokenType or \ 918 extensionBase == DateTimeType or \ 919 extensionBase == DateType or \ 920 extensionBase in IntegerType or \ 921 extensionBase == DecimalType or \ 922 extensionBase == PositiveIntegerType or \ 923 extensionBase == NegativeIntegerType or \ 924 extensionBase == NonPositiveIntegerType or \ 925 extensionBase == NonNegativeIntegerType or \ 926 extensionBase == BooleanType or \ 927 extensionBase == FloatType or \ 928 extensionBase == DoubleType or \ 929 extensionBase in OtherSimpleTypes: 930 pass 931 else: 932 self.stack[-1].setBase(extensionBase) 933 elif name == AnyAttributeType: 934 # Mark the current element as containing anyAttribute. 935 self.stack[-1].setAnyAttribute(1) 936 elif name == SimpleTypeType: 937 # Save the name of the simpleType, but ignore everything 938 # else about it (for now). 939 if 'name' in attrs.keys(): 940 stName = cleanupName(attrs['name']) 941 else: 942 stName = None 943 # If the parent is an element, mark it as a simpleType. 944 if len(self.stack) > 0: 945 self.stack[-1].setSimpleType(1) 946 element = SimpleTypeElement(stName) 947 SimpleTypeDict[stName] = element 948 self.stack.append(element) 949 self.inSimpleType = 1 950 elif name == RestrictionType: 951 # If we are in a simpleType, capture the name of 952 # the restriction base. 953 if self.inSimpleType and 'base' in attrs.keys(): 954 self.stack[-1].setBase(attrs['base']) 955 self.inRestrictionType = 1 956 elif name == EnumerationType: 957 if self.inAttribute and attrs.has_key('value'): 958 # We know that the restriction is on an attribute and the 959 # attributes of the current element are un-ordered so the 960 # instance variable "lastAttribute" will have our attribute. 961 self.lastAttribute.values.append(attrs['value']) 962 elif self.inElement and attrs.has_key('value'): 963 # We're not in an attribute so the restriction must have 964 # been placed on an element and that element will still be 965 # in the stack. We search backwards through the stack to 966 # find the last element. 967 element = None 968 for entry in list(stack).reverse(): 969 if type(entry) == XschemaElement: 970 element = entry 971 if element is None: 972 sys.stderr.write( 973 'Cannot find element to attach enumeration: %s' % \ 974 value) 975 sys.exit(-1) 976 element.values.append(attrs['value']) 977 elif self.inSimpleType and attrs.has_key('value'): 978 # We've been defined as a simpleType on our own. 979 self.stack[-1].values.append(attrs['value']) 980 elif name == UnionType: 981 # Union types are only used with a parent simpleType and we want 982 # the parent to know what it's a union of. 983 if attrs.has_key('memberTypes'): 984 for member in attrs['memberTypes'].split(" "): 985 self.stack[-1].unionOf.append(member) 986 elif name == WhiteSpaceType and self.inRestrictionType: 987 if attrs.has_key('value'): 988 if attrs.getValue('value') == 'collapse': 989 self.stack[-1].collapseWhiteSpace = 1 990 elif name == ListType: 991 self.inListType = 1 992 #ipshell('Parsing simpleType -- Entering ipshell.\nHit Ctrl-D to exit') 993 #import pdb; pdb.set_trace() 994 logging.debug("Start element stack: %d" % len(self.stack))
995
996 - def endElement(self, name):
997 logging.debug("End element: %s" % (name)) 998 logging.debug("End element stack: %d" % (len(self.stack))) 999 if name == SimpleTypeType and self.inSimpleType: 1000 self.inSimpleType = 0 1001 # If the simpleType is directly off the root, it may be used to 1002 # qualify the type of many elements and/or attributes so we 1003 # don't want to loose it entirely. 1004 simpleType = self.stack.pop() 1005 if len(self.stack) == 1: 1006 self.topLevelSimpleTypes.append(simpleType) 1007 elif name == RestrictionType and self.inRestrictionType: 1008 self.inRestrictionType = 0 1009 elif name == ElementType or (name == ComplexTypeType and self.stack[-1].complexType): 1010 self.inElement = 0 1011 self.inNonanonymousComplexType = 0 1012 element = self.stack.pop() 1013 self.stack[-1].addChild(element) 1014 elif name == ComplexTypeType: 1015 self.inComplexType = 0 1016 elif name == SequenceType: 1017 self.inSequence = 0 1018 elif name == ChoiceType: 1019 self.currentChoice = None 1020 self.inChoice = 0 1021 elif name == AttributeType: 1022 self.inAttribute = 0 1023 elif name == AttributeGroupType: 1024 self.inAttributeGroup = 0 1025 if self.stack[-1].attributeGroup: 1026 # The top of the stack contains an XschemaElement which 1027 # contains the definition of an attributeGroup. 1028 # Save this attributeGroup in the 1029 # global AttributeGroup dictionary. 1030 attributeGroup = self.stack[-1].attributeGroup 1031 name = attributeGroup.getName() 1032 AttributeGroups[name] = attributeGroup 1033 self.stack[-1].attributeGroup = None 1034 self.stack.pop() 1035 else: 1036 # This is a reference to an attributeGroup. 1037 # We have already added it to the list of attributeGroup names. 1038 # Leave it. We'll fill it in during annotate. 1039 pass 1040 elif name == SchemaType: 1041 self.inSchema = 0 1042 if len(self.stack) != 1: 1043 print '*** error stack. len(self.stack): %d' % len(self.stack) 1044 sys.exit(-1) 1045 logging.debug("Previous root:", self.root) 1046 self.root = self.stack[0] 1047 logging.debug("New root:", self.root) 1048 elif name == ComplexContentType: 1049 pass 1050 elif name == ExtensionType: 1051 pass 1052 elif name == ListType: 1053 # List types are only used with a parent simpleType and can have a 1054 # simpleType child. So, if we're in a list type we have to be 1055 # careful to reset the inSimpleType flag otherwise the handler's 1056 # internal stack will not be unrolled correctly. 1057 self.inSimpleType = 1 1058 self.inListType = 0
1059
1060 - def characters(self, chrs):
1061 if self.inElement: 1062 pass 1063 elif self.inComplexType: 1064 pass 1065 elif self.inSequence: 1066 pass 1067 elif self.inChoice: 1068 pass
1069 1070 1071 # 1072 # Code generation 1073 # 1074
1075 -def generateExportFn_1(outfile, child, name, fill):
1076 cleanName = cleanupName(name) 1077 mappedName = mapName(cleanName) 1078 if child.getType() in StringType or \ 1079 child.getType() == TokenType or \ 1080 child.getType() == DateTimeType or \ 1081 child.getType() == DateType: 1082 s1 = '%s showIndent(outfile, level)\n' % fill 1083 outfile.write(s1) 1084 s1 = "%s outfile.write('<%s>%%s</%s>\\n' %% quote_xml(self.get%s()))\n" % \ 1085 (fill, name, name, make_gs_name(cleanName)) 1086 outfile.write(s1) 1087 elif child.getType() in IntegerType or \ 1088 child.getType() == BooleanType or \ 1089 child.getType() == PositiveIntegerType or \ 1090 child.getType() == NonPositiveIntegerType or \ 1091 child.getType() == NegativeIntegerType or \ 1092 child.getType() == NonNegativeIntegerType: 1093 s1 = '%s showIndent(outfile, level)\n' % fill 1094 outfile.write(s1) 1095 s1 = "%s outfile.write('<%s>%%d</%s>\\n' %% self.get%s())\n" % \ 1096 (fill, name, name, make_gs_name(cleanName)) 1097 outfile.write(s1) 1098 elif child.getType() == FloatType or \ 1099 child.getType() == DecimalType: 1100 s1 = '%s showIndent(outfile, level)\n' % fill 1101 outfile.write(s1) 1102 s1 = "%s outfile.write('<%s>%%f</%s>\\n' %% self.get%s())\n" % \ 1103 (fill, name, name, make_gs_name(cleanName)) 1104 outfile.write(s1) 1105 elif child.getType() == DoubleType: 1106 s1 = '%s showIndent(outfile, level)\n' % fill 1107 outfile.write(s1) 1108 s1 = "%s outfile.write('<%s>%%e</%s>\\n' %% self.get%s())\n" % \ 1109 (fill, name, name, make_gs_name(cleanName)) 1110 outfile.write(s1) 1111 else: 1112 s1 = "%s if self.%s:\n" % (fill, mappedName) 1113 outfile.write(s1) 1114 if name == child.getType(): 1115 s1 = "%s self.%s.export(outfile, level)\n" % \ 1116 (fill, mappedName) 1117 else: 1118 s1 = "%s self.%s.export(outfile, level, name_='%s')\n" % \ 1119 (fill, mappedName, name) 1120 outfile.write(s1)
1121 1122
1123 -def generateExportFn_2(outfile, child, name, fill):
1124 cleanName = cleanupName(name) 1125 mappedName = mapName(cleanName) 1126 s1 = "%s for %s_ in self.get%s():\n" % (fill, cleanName, make_gs_name(cleanName)) 1127 outfile.write(s1) 1128 if child.getType() in StringType or \ 1129 child.getType() == TokenType or \ 1130 child.getType() == DateTimeType or \ 1131 child.getType() == DateType: 1132 s1 = '%s showIndent(outfile, level)\n' % fill 1133 outfile.write(s1) 1134 s1 = "%s outfile.write('<%s>%%s</%s>\\n' %% quote_xml(%s_))\n" % \ 1135 (fill, name, name, cleanName,) 1136 outfile.write(s1) 1137 elif child.getType() in IntegerType or \ 1138 child.getType() == BooleanType or \ 1139 child.getType() == PositiveIntegerType or \ 1140 child.getType() == NonPositiveIntegerType or \ 1141 child.getType() == NegativeIntegerType or \ 1142 child.getType() == NonNegativeIntegerType: 1143 s1 = '%s showIndent(outfile, level)\n' % fill 1144 outfile.write(s1) 1145 s1 = "%s outfile.write('<%s>%%d</%s>\\n' %% %s_)\n" % \ 1146 (fill, name, name, cleanName,) 1147 outfile.write(s1) 1148 elif child.getType() == FloatType or \ 1149 child.getType() == DecimalType: 1150 s1 = '%s showIndent(outfile, level)\n' % fill 1151 outfile.write(s1) 1152 s1 = "%s outfile.write('<%s>%%f</%s>\\n' %% %s_)\n" % \ 1153 (fill, name, name, cleanName,) 1154 outfile.write(s1) 1155 elif child.getType() == DoubleType: 1156 s1 = '%s showIndent(outfile, level)\n' % fill 1157 outfile.write(s1) 1158 s1 = "%s outfile.write('<%s>%%e</%s>\\n' %% %s_)\n" % \ 1159 (fill, name, name, cleanName) 1160 outfile.write(s1) 1161 else: 1162 if name == child.getType(): 1163 s1 = "%s %s_.export(outfile, level)\n" % (fill, mappedName) 1164 else: 1165 s1 = "%s %s_.export(outfile, level, name_='%s')\n" % \ 1166 (fill, mappedName, cleanName,) 1167 outfile.write(s1)
1168 1169
1170 -def generateExportFn_3(outfile, child, name, fill):
1171 cleanName = cleanupName(name) 1172 mappedName = mapName(cleanName) 1173 s1 = "%s if self.get%s() != None :\n" % ( 1174 fill, make_gs_name(cleanName)) 1175 outfile.write(s1) 1176 if child.getType() in StringType or \ 1177 child.getType() == TokenType or \ 1178 child.getType() == DateTimeType or \ 1179 child.getType() == DateType: 1180 s1 = '%s showIndent(outfile, level)\n' % fill 1181 outfile.write(s1) 1182 s1 = "%s outfile.write('<%s>%%s</%s>\\n' %% quote_xml(self.get%s()))\n" % \ 1183 (fill, name, name, make_gs_name(cleanName)) 1184 outfile.write(s1) 1185 elif child.getType() in IntegerType or \ 1186 child.getType() == BooleanType or \ 1187 child.getType() == PositiveIntegerType or \ 1188 child.getType() == NonPositiveIntegerType or \ 1189 child.getType() == NegativeIntegerType or \ 1190 child.getType() == NonNegativeIntegerType: 1191 s1 = '%s showIndent(outfile, level)\n' % fill 1192 outfile.write(s1) 1193 s1 = "%s outfile.write('<%s>%%d</%s>\\n' %% self.get%s())\n" % \ 1194 (fill, name, name, make_gs_name(cleanName)) 1195 outfile.write(s1) 1196 elif child.getType() == FloatType or \ 1197 child.getType() == DecimalType: 1198 s1 = '%s showIndent(outfile, level)\n' % fill 1199 outfile.write(s1) 1200 s1 = "%s outfile.write('<%s>%%f</%s>\\n' %% self.get%s())\n" % \ 1201 (fill, name, name, make_gs_name(cleanName)) 1202 outfile.write(s1) 1203 elif child.getType() == DoubleType: 1204 s1 = '%s showIndent(outfile, level)\n' % fill 1205 outfile.write(s1) 1206 s1 = "%s outfile.write('<%s>%%e</%s>\\n' %% self.get%s())\n" % \ 1207 (fill, name, name, make_gs_name(cleanName)) 1208 outfile.write(s1) 1209 else: 1210 s1 = "%s if self.%s:\n" % (fill, mappedName) 1211 outfile.write(s1) 1212 if name == child.getType(): 1213 s1 = "%s self.%s.export(outfile, level)\n" % \ 1214 (fill, mappedName) 1215 else: 1216 s1 = "%s self.%s.export(outfile, level, name_='%s')\n" % \ 1217 (fill, mappedName, name) 1218 outfile.write(s1)
1219 1220
1221 -def generateExportAttributes(outfile, element, hasAttributes):
1222 if len(element.getAttributeDefs()) > 0: 1223 hasAttributes += 1 1224 attrDefs = element.getAttributeDefs() 1225 for key in attrDefs.keys(): 1226 attrDef = attrDefs[key] 1227 name = attrDef.getName() 1228 cleanName = cleanupName(name) 1229 capName = make_gs_name(cleanName) 1230 if attrDef.getUse() == 'optional': 1231 s1 = " if self.get%s() is not None:\n" % (capName,) 1232 outfile.write(s1) 1233 s1 = " outfile.write(' %s=\"%%s\"' %% (self.get%s(), ))\n" % \ 1234 (name, capName,) 1235 outfile.write(s1) 1236 else: 1237 s1 = " outfile.write(' %s=\"%%s\"' %% (self.get%s(), ))\n" % \ 1238 (name, capName,) 1239 outfile.write(s1) 1240 if element.getAnyAttribute(): 1241 s1 = ' for name, value in self.anyAttributes_.items():\n' 1242 outfile.write(s1) 1243 s1 = " outfile.write(' %s=\"%s\"' % (name, value, ))\n" 1244 outfile.write(s1) 1245 return hasAttributes
1246 1247
1248 -def generateExportChildren(outfile, element, hasChildren):
1249 if len(element.getChildren()) > 0: 1250 hasChildren += 1 1251 if element.isMixed(): 1252 s1 = " for item_ in self.content_:\n" 1253 outfile.write(s1) 1254 s1 = " item_.export(outfile, level, name_)\n" 1255 outfile.write(s1) 1256 else: 1257 for child in element.getChildren(): 1258 name = child.getName() 1259 if child.getMaxOccurs() > 1: 1260 generateExportFn_2(outfile, child, name, ' ') 1261 else: 1262 if (child.getOptional()): 1263 generateExportFn_3(outfile, child, name, '') 1264 else: 1265 generateExportFn_1(outfile, child, name, '') 1266 ## base = element.getBase() 1267 ## if base and base in ElementDict: 1268 ## parent = ElementDict[base] 1269 ## hasAttributes = generateExportChildren(outfile, parent, hasChildren) 1270 return hasChildren
1271 1272
1273 -def countChildren(element, count):
1274 count += len(element.getChildren()) 1275 base = element.getBase() 1276 if base and base in ElementDict: 1277 parent = ElementDict[base] 1278 count = countChildren(parent, count) 1279 return count
1280 1281
1282 -def generateExportFn(outfile, prefix, element):
1283 childCount = countChildren(element, 0) 1284 base = element.getBase() 1285 s1 = " def export(self, outfile, level, name_='%s'):\n" % \ 1286 element.getName() 1287 outfile.write(s1) 1288 s1 = ' showIndent(outfile, level)\n' 1289 outfile.write(s1) 1290 if len(element.getAttributeDefs()) > 0 or element.getAnyAttribute(): 1291 s1 = " outfile.write('<%s' % (name_, ))\n" 1292 outfile.write(s1) 1293 1294 s1 = " self.exportAttributes(outfile, level, name_='%s')\n" % \ 1295 element.getName() 1296 outfile.write(s1) 1297 if element.isMixed() or childCount == 0: 1298 s1 = " outfile.write('>')\n" 1299 else: 1300 s1 = " outfile.write('>\\n')\n" 1301 outfile.write(s1) 1302 else: 1303 if element.isMixed() or childCount == 0: 1304 s1 = " outfile.write('<%s>' % name_)\n" 1305 else: 1306 s1 = " outfile.write('<%s>\\n' % name_)\n" 1307 outfile.write(s1) 1308 1309 s1 = " self.exportChildren(outfile, level + 1, name_)\n" 1310 outfile.write(s1) 1311 if element.isMixed() or childCount == 0: 1312 s1 = " outfile.write('</%s>\\n' % name_)\n" 1313 outfile.write(s1) 1314 else: 1315 s1 = ' showIndent(outfile, level)\n' 1316 outfile.write(s1) 1317 s1 = " outfile.write('</%s>\\n' % name_)\n" 1318 outfile.write(s1) 1319 s1 = " def exportAttributes(self, outfile, level, name_='%s'):\n" % \ 1320 element.getName() 1321 outfile.write(s1) 1322 hasAttributes = 0 1323 hasAttributes = generateExportAttributes(outfile, element, hasAttributes) 1324 if base and base not in SimpleTypeDict: 1325 hasAttributes += 1 1326 s1 = " %s.exportAttributes(self, outfile, level, name_='%s')\n" % \ 1327 (base, element.getName(),) 1328 outfile.write(s1) 1329 if hasAttributes == 0: 1330 s1 = " pass\n" 1331 outfile.write(s1) 1332 ## if len(element.getChildren()) > 0 and not element.isMixed(): 1333 ## s1 = ' showIndent(outfile, level)\n' 1334 ## outfile.write(s1) 1335 s1 = " def exportChildren(self, outfile, level, name_='%s'):\n" % \ 1336 element.getName() 1337 outfile.write(s1) 1338 hasChildren = 0 1339 hasChildren = generateExportChildren(outfile, element, hasChildren) 1340 if base and base not in SimpleTypeDict: 1341 hasChildren += 1 1342 s1 = " %s.exportChildren(self, outfile, level, name_)\n" % (base,) 1343 outfile.write(s1) 1344 if childCount == 0: 1345 s1 = " outfile.write(self.valueOf_)\n" 1346 outfile.write(s1)
1347 # end generateExportFn 1348 1349 # Modified by EDNA
1350 -def generateExportFnXML(outfile, prefix, element):
1351 s1 = " #Only to export the entire XML tree to a file stream on disk\n" 1352 s2 = " def outputFile( self, _outfileName ):\n" 1353 outfile.write("\n") 1354 outfile.write(s1) 1355 outfile.write(s2) 1356 outfile.write(' outfile = open( _outfileName, "w" )\n') 1357 outfile.write(' outfile.write(\"<?xml version=\\"1.0\\" ?>\\n\")\n') 1358 outfile.write(' self.export( outfile, 0, name_=\'%s\' )\n' % element.getName()) 1359 outfile.write(' outfile.close()\n') 1360 outfile.write("\n")
1361
1362 -def generateStaticParseString(outfile, prefix, element):
1363 s1 = " #Static method for parsing a string\n" 1364 s2 = " def parseString( _inString ):\n" 1365 outfile.write("\n") 1366 outfile.write(s1) 1367 outfile.write(s2) 1368 outfile.write(' doc = minidom.parseString(_inString)\n') 1369 outfile.write(' rootNode = doc.documentElement\n') 1370 outfile.write(' rootObj = %s.factory()\n' % element.getName()) 1371 outfile.write(' rootObj.build(rootNode)\n') 1372 outfile.write(' return rootObj\n') 1373 outfile.write(' parseString = staticmethod( parseString ) \n') 1374 outfile.write("\n")
1375
1376 -def generateStaticParseFile(outfile, prefix, element):
1377 s1 = " #Static method for parsing a file\n" 1378 s2 = " def parseFile( _inFilePath ):\n" 1379 outfile.write("\n") 1380 outfile.write(s1) 1381 outfile.write(s2) 1382 outfile.write(' doc = minidom.parse(_inFilePath)\n') 1383 outfile.write(' rootNode = doc.documentElement\n') 1384 outfile.write(' rootObj = %s.factory()\n' % element.getName()) 1385 outfile.write(' rootObj.build(rootNode)\n') 1386 outfile.write(' return rootObj\n') 1387 outfile.write(' parseFile = staticmethod( parseFile ) \n') 1388 outfile.write("\n")
1389
1390 -def generateMarshal(outfile, prefix, element):
1391 s1 = " #Method for marshalling an object\n" 1392 s2 = " def marshal( self ):\n" 1393 outfile.write("\n") 1394 outfile.write(s1) 1395 outfile.write(s2) 1396 outfile.write(' oStreamString = StringIO.StringIO()\n') 1397 outfile.write(' oStreamString.write(\'<?xml version="1.0" ?>\\n\')\n') 1398 outfile.write(' self.export( oStreamString, 0, name_="%s" )\n' % element.getName()) 1399 outfile.write(' oStringXML = oStreamString.getvalue()\n') 1400 outfile.write(' oStreamString.close()\n') 1401 outfile.write(' return oStringXML\n') 1402 outfile.write("\n")
1403 1404 # 1405 # Generate exportLiteral method. 1406 # 1407
1408 -def generateExportLiteralFn_1(outfile, child, name, fill):
1409 cleanName = cleanupName(name) 1410 mappedName = mapName(cleanName) 1411 if child.getType() in StringType or \ 1412 child.getType() == TokenType or \ 1413 child.getType() == DateTimeType or \ 1414 child.getType() == DateType: 1415 s1 = '%s showIndent(outfile, level)\n' % fill 1416 outfile.write(s1) 1417 s1 = "%s outfile.write('%s=%%s,\\n' %% quote_python(self.get%s()))\n" % \ 1418 (fill, mappedName, make_gs_name(name)) 1419 outfile.write(s1) 1420 elif child.getType() in IntegerType or \ 1421 child.getType() == BooleanType or \ 1422 child.getType() == PositiveIntegerType or \ 1423 child.getType() == NonPositiveIntegerType or \ 1424 child.getType() == NegativeIntegerType or \ 1425 child.getType() == NonNegativeIntegerType: 1426 s1 = '%s showIndent(outfile, level)\n' % fill 1427 outfile.write(s1) 1428 s1 = "%s outfile.write('%s=%%d,\\n' %% self.get%s())\n" % \ 1429 (fill, mappedName, make_gs_name(name)) 1430 outfile.write(s1) 1431 elif child.getType() == FloatType or \ 1432 child.getType() == DecimalType: 1433 s1 = '%s showIndent(outfile, level)\n' % fill 1434 outfile.write(s1) 1435 s1 = "%s outfile.write('%s=%%f,\\n' %% self.get%s())\n" % \ 1436 (fill, mappedName, make_gs_name(name)) 1437 outfile.write(s1) 1438 elif child.getType() == DoubleType: 1439 s1 = '%s showIndent(outfile, level)\n' % fill 1440 outfile.write(s1) 1441 s1 = "%s outfile.write('%s=%%e,\\n' %% self.get%s())\n" % \ 1442 (fill, name, make_gs_name(name)) 1443 outfile.write(s1) 1444 else: 1445 s1 = "%s if self.%s:\n" % (fill, mappedName) 1446 outfile.write(s1) 1447 s1 = '%s showIndent(outfile, level)\n' % fill 1448 outfile.write(s1) 1449 s1 = "%s outfile.write('%s=%s(\\n')\n" % \ 1450 (fill, mappedName, mapName(cleanupName(child.getType()))) 1451 outfile.write(s1) 1452 if name == child.getType(): 1453 s1 = "%s self.%s.exportLiteral(outfile, level)\n" % \ 1454 (fill, mappedName) 1455 else: 1456 s1 = "%s self.%s.exportLiteral(outfile, level, name_='%s')\n" % \ 1457 (fill, mappedName, name) 1458 outfile.write(s1) 1459 s1 = '%s showIndent(outfile, level)\n' % fill 1460 outfile.write(s1) 1461 s1 = "%s outfile.write('),\\n')\n" % (fill,) 1462 outfile.write(s1)
1463 1464
1465 -def generateExportLiteralFn_2(outfile, child, name, fill):
1466 if child.getType() in StringType or \ 1467 child.getType() == TokenType or \ 1468 child.getType() == DateTimeType or \ 1469 child.getType() == DateType: 1470 s1 = '%s showIndent(outfile, level)\n' % fill 1471 outfile.write(s1) 1472 s1 = "%s outfile.write('%%s,\\n' %% quote_python(%s))\n" % \ 1473 (fill, name) 1474 outfile.write(s1) 1475 elif child.getType() in IntegerType or \ 1476 child.getType() == BooleanType or \ 1477 child.getType() == PositiveIntegerType or \ 1478 child.getType() == NonPositiveIntegerType or \ 1479 child.getType() == NegativeIntegerType or \ 1480 child.getType() == NonNegativeIntegerType: 1481 s1 = '%s showIndent(outfile, level)\n' % fill 1482 outfile.write(s1) 1483 s1 = "%s outfile.write('%%d,\\n' %% %s)\n" % \ 1484 (fill, name) 1485 outfile.write(s1) 1486 elif child.getType() == FloatType or \ 1487 child.getType() == DecimalType: 1488 s1 = '%s showIndent(outfile, level)\n' % fill 1489 outfile.write(s1) 1490 s1 = "%s outfile.write('%%f,\\n' %% %s)\n" % \ 1491 (fill, name) 1492 outfile.write(s1) 1493 elif child.getType() == DoubleType: 1494 s1 = '%s showIndent(outfile, level)\n' % fill 1495 outfile.write(s1) 1496 s1 = "%s outfile.write('%%e,\\n' %% %s)\n" % \ 1497 (fill, name) 1498 outfile.write(s1) 1499 else: 1500 s1 = '%s showIndent(outfile, level)\n' % fill 1501 outfile.write(s1) 1502 s1 = "%s outfile.write('%s(\\n')\n" % \ 1503 (fill, cleanupName(child.getType())) 1504 outfile.write(s1) 1505 if name == child.getType(): 1506 s1 = "%s %s.exportLiteral(outfile, level)\n" % (fill, child.getType()) 1507 else: 1508 s1 = "%s %s.exportLiteral(outfile, level, name_='%s')\n" % \ 1509 (fill, name, name) 1510 outfile.write(s1) 1511 s1 = '%s showIndent(outfile, level)\n' % fill 1512 outfile.write(s1) 1513 s1 = "%s outfile.write('),\\n')\n" % (fill,) 1514 outfile.write(s1)
1515 1516
1517 -def generateExportLiteralFn(outfile, prefix, element):
1518 base = element.getBase() 1519 s1 = " def exportLiteral(self, outfile, level, name_='%s'):\n" % element.getName() 1520 outfile.write(s1) 1521 s1 = " level += 1\n" 1522 outfile.write(s1) 1523 s1 = " self.exportLiteralAttributes(outfile, level, name_)\n" 1524 outfile.write(s1) 1525 s1 = " self.exportLiteralChildren(outfile, level, name_)\n" 1526 outfile.write(s1) 1527 s1 = " def exportLiteralAttributes(self, outfile, level, name_):\n" 1528 outfile.write(s1) 1529 count = 0 1530 attrDefs = element.getAttributeDefs() 1531 for key in attrDefs: 1532 attrDef = attrDefs[key] 1533 count += 1 1534 name = attrDef.getName() 1535 cleanName = cleanupName(name) 1536 capName = make_gs_name(cleanName) 1537 mappedName = mapName(cleanName) 1538 s1 = " showIndent(outfile, level)\n" 1539 outfile.write(s1) 1540 stringType = 0 1541 data_type = attrDef.getData_type() 1542 if data_type.find('string') >= 0: 1543 stringType = 1 1544 else: 1545 stringType = 1 1546 if stringType: 1547 s1 = " outfile.write('%s = \"%%s\",\\n' %% (self.get%s(),))\n" % \ 1548 (mappedName, capName,) 1549 else: 1550 s1 = " outfile.write('%s = %%s,\\n' %% (self.get%s(),))\n" % \ 1551 (mappedName, capName,) 1552 outfile.write(s1) 1553 if element.getAnyAttribute(): 1554 count += 1 1555 s1 = ' for name, value in self.anyAttributes_.items():\n' 1556 outfile.write(s1) 1557 s1 = ' showIndent(outfile, level)\n' 1558 outfile.write(s1) 1559 s1 = " outfile.write('%s = \"%s\",\\n' % (name, value,))\n" 1560 outfile.write(s1) 1561 if count == 0: 1562 s1 = " pass\n" 1563 outfile.write(s1) 1564 if base and base not in SimpleTypeDict: 1565 s1 = " %s.exportLiteralAttributes(self, outfile, level, name_)\n" % \ 1566 (base,) 1567 outfile.write(s1) 1568 s1 = " def exportLiteralChildren(self, outfile, level, name_):\n" 1569 outfile.write(s1) 1570 for child in element.getChildren(): 1571 name = child.getName() 1572 name = cleanupName(name) 1573 #unmappedName = child.getUnmappedCleanName() 1574 #cleanName = cleanupName(name) 1575 #mappedName = mapName(cleanName) 1576 if element.isMixed(): 1577 s1 = " showIndent(outfile, level)\n" 1578 outfile.write(s1) 1579 s1 = " outfile.write('content_ = [\\n')\n" 1580 outfile.write(s1) 1581 s1 = ' for item_ in self.content_:\n' 1582 outfile.write(s1) 1583 s1 = ' item_.exportLiteral(outfile, level, name_)\n' 1584 outfile.write(s1) 1585 s1 = " showIndent(outfile, level)\n" 1586 outfile.write(s1) 1587 s1 = " outfile.write('],\\n')\n" 1588 outfile.write(s1) 1589 else: 1590 if child.getMaxOccurs() > 1: 1591 s1 = " showIndent(outfile, level)\n" 1592 outfile.write(s1) 1593 s1 = " outfile.write('%s=[\\n')\n" % name 1594 outfile.write(s1) 1595 s1 = " level += 1\n" 1596 outfile.write(s1) 1597 s1 = " for %s in self.%s:\n" % (name, name) 1598 outfile.write(s1) 1599 generateExportLiteralFn_2(outfile, child, name, ' ') 1600 s1 = " level -= 1\n" 1601 outfile.write(s1) 1602 s1 = " showIndent(outfile, level)\n" 1603 outfile.write(s1) 1604 s1 = " outfile.write('],\\n')\n" 1605 outfile.write(s1) 1606 else: 1607 generateExportLiteralFn_1(outfile, child, name, '') 1608 if len(element.getChildren()) == 0: 1609 s1 = " showIndent(outfile, level)\n" 1610 outfile.write(s1) 1611 s1 = " outfile.write('valueOf_ = \"%s\",\\n' % (self.valueOf_,))\n" 1612 outfile.write(s1) 1613 if base and base not in SimpleTypeDict: 1614 s1 = " %s.exportLiteralChildren(self, outfile, level, name_)\n" % \ 1615 (base,) 1616 outfile.write(s1)
1617 #s1 = " level -= 1\n" 1618 #outfile.write(s1) 1619 # end generateExportLiteralFn 1620 1621 # 1622 # Generate build method. 1623 # 1624
1625 -def generateBuildAttributes(outfile, element, hasAttributes):
1626 attrDefs = element.getAttributeDefs() 1627 for key in attrDefs: 1628 attrDef = attrDefs[key] 1629 hasAttributes += 1 1630 name = attrDef.getName() 1631 cleanName = cleanupName(name) 1632 mappedName = mapName(cleanName) 1633 atype = attrDef.getData_type() 1634 if atype in IntegerType or \ 1635 atype == PositiveIntegerType or \ 1636 atype == NonPositiveIntegerType or \ 1637 atype == NegativeIntegerType or \ 1638 atype == NonNegativeIntegerType: 1639 s1 = " if attrs.get('%s'):\n" % name 1640 outfile.write(s1) 1641 s1 = ' try:\n' 1642 outfile.write(s1) 1643 s1 = " self.%s = int(attrs.get('%s').value)\n" % \ 1644 (mappedName, name) 1645 outfile.write(s1) 1646 s1 = ' except ValueError:\n' 1647 outfile.write(s1) 1648 s1 = " raise ValueError('Bad integer attribute (%s)')\n" % \ 1649 (name,) 1650 outfile.write(s1) 1651 if atype == PositiveIntegerType: 1652 s1 = ' if self.%s <= 0:\n' % mappedName 1653 outfile.write(s1) 1654 s1 = " raise ValueError('Invalid PositiveInteger (%s)')\n" % name 1655 outfile.write(s1) 1656 elif atype == NonPositiveIntegerType: 1657 s1 = ' if self.%s > 0:\n' % mappedName 1658 outfile.write(s1) 1659 s1 = " raise ValueError('Invalid NonPositiveInteger (%s)')\n" % name 1660 outfile.write(s1) 1661 elif atype == NegativeIntegerType: 1662 s1 = ' if self.%s >= 0:\n' % mappedName 1663 outfile.write(s1) 1664 s1 = " raise ValueError('Invalid NegativeInteger (%s)')\n" % name 1665 outfile.write(s1) 1666 elif atype == NonNegativeIntegerType: 1667 s1 = ' if self.%s < 0:\n' % mappedName 1668 outfile.write(s1) 1669 s1 = " raise ValueError('Invalid NonNegativeInteger (%s)')\n" % name 1670 outfile.write(s1) 1671 elif atype == BooleanType: 1672 s1 = " if attrs.get('%s'):\n" % (name,) 1673 outfile.write(s1) 1674 s1 = " if attrs.get('%s').value in ('true', '1'):\n" % \ 1675 (name,) 1676 outfile.write(s1) 1677 s1 = " self.%s = 1\n" % (mappedName,) 1678 outfile.write(s1) 1679 s1 = " elif attrs.get('%s').value in ('false', '0'):\n" % \ 1680 (name,) 1681 outfile.write(s1) 1682 s1 = " self.%s = 0\n" % (mappedName,) 1683 outfile.write(s1) 1684 s1 = ' else:\n' 1685 outfile.write(s1) 1686 s1 = " raise ValueError('Bad boolean attribute (%s)')\n" % \ 1687 (name,) 1688 outfile.write(s1) 1689 elif atype == FloatType or atype == DoubleType or atype == DecimalType: 1690 s1 = " if attrs.get('%s'):\n" % (name,) 1691 outfile.write(s1) 1692 s1 = ' try:\n' 1693 outfile.write(s1) 1694 s1 = " self.%s = float(attrs.get('%s').value)\n" % \ 1695 (mappedName, name,) 1696 outfile.write(s1) 1697 s1 = ' except Exception:\n' 1698 outfile.write(s1) 1699 s1 = " raise ValueError('Bad float/double attribute (%s)')\n" % \ 1700 (name,) 1701 outfile.write(s1) 1702 elif atype == TokenType: 1703 s1 = " if attrs.get('%s'):\n" % (name,) 1704 outfile.write(s1) 1705 s1 = " self.%s = attrs.get('%s').value\n" % \ 1706 (mappedName, name,) 1707 outfile.write(s1) 1708 s1 = " self.%s = ' '.join(self.%s.split())\n" % \ 1709 (mappedName, mappedName,) 1710 outfile.write(s1) 1711 else: 1712 # Assume attr['type'] in StringType or attr['type'] == DateTimeType: 1713 s1 = " if attrs.get('%s'):\n" % (name,) 1714 outfile.write(s1) 1715 s1 = " self.%s = attrs.get('%s').value\n" % \ 1716 (mappedName, name,) 1717 outfile.write(s1) 1718 if element.getAnyAttribute(): 1719 hasAttributes += 1 1720 s1 = ' self.anyAttributes_ = {}\n' 1721 outfile.write(s1) 1722 s1 = ' for name, value in attrs.items():\n' 1723 outfile.write(s1) 1724 if len(attrDefs) > 0: 1725 s1List = [' if'] 1726 firstTime = 1 1727 for key in attrDefs: 1728 if firstTime: 1729 s1List.append(' name != "%s"' % key) 1730 firstTime = 0 1731 else: 1732 s1List.append(' and name != "%s"' % key) 1733 s1List.append(':\n') 1734 s1 = ''.join(s1List) 1735 outfile.write(s1) 1736 s1 = ' self.anyAttributes_[name] = value\n' 1737 outfile.write(s1) 1738 else: 1739 s1 = ' self.anyAttributes_[name] = value\n' 1740 outfile.write(s1) 1741 return hasAttributes
1742 1743
1744 -def generateBuildMixed_1(outfile, prefix, child, headChild, keyword, delayed):
1745 global DelayedElements, DelayedElements_subclass 1746 nestedElements = 1 1747 origName = child.getName() 1748 name = child.getCleanName() 1749 headName = cleanupName(headChild.getName()) 1750 childType = child.getType() 1751 if childType in StringType or \ 1752 childType == TokenType or \ 1753 childType == DateTimeType or \ 1754 childType == DateType: 1755 s1 = ' %s child_.nodeType == Node.ELEMENT_NODE and \\\n' % \ 1756 keyword 1757 outfile.write(s1) 1758 s1 = " nodeName_ == '%s':\n" % origName 1759 outfile.write(s1) 1760 s1 = " value_ = []\n" 1761 outfile.write(s1) 1762 s1 = " for text_ in child_.childNodes:\n" 1763 outfile.write(s1) 1764 s1 = " value_.append(text_.nodeValue)\n" 1765 outfile.write(s1) 1766 s1 = " valuestr_ = ''.join(value_)\n" 1767 outfile.write(s1) 1768 if childType == TokenType: 1769 s1 = " valuestr_ = ' '.join(valuestr_.split())\n" 1770 outfile.write(s1) 1771 s1 = " obj_ = self.mixedclass_(MixedContainer.CategorySimple,\n" 1772 outfile.write(s1) 1773 s1 = " MixedContainer.TypeString, '%s', valuestr_)\n" % \ 1774 origName 1775 outfile.write(s1) 1776 s1 = " self.content_.append(obj_)\n" 1777 outfile.write(s1) 1778 elif childType in IntegerType or \ 1779 childType == PositiveIntegerType or \ 1780 childType == NonPositiveIntegerType or \ 1781 childType == NegativeIntegerType or \ 1782 childType == NonNegativeIntegerType: 1783 s1 = " %s child_.nodeType == Node.ELEMENT_NODE and \\\n" % \ 1784 keyword 1785 outfile.write(s1) 1786 s1 = " nodeName_ == '%s':\n" % origName 1787 outfile.write(s1) 1788 s1 = " if child_.firstChild:\n" 1789 outfile.write(s1) 1790 s1 = " sval_ = child_.firstChild.nodeValue\n" 1791 outfile.write(s1) 1792 s1 = " try:\n" 1793 outfile.write(s1) 1794 s1 = " ival_ = int(sval_)\n" 1795 outfile.write(s1) 1796 s1 = " except ValueError:\n" 1797 outfile.write(s1) 1798 s1 = " raise ValueError('requires integer -- %s' % child_.toxml())\n" 1799 outfile.write(s1) 1800 if childType == PositiveIntegerType: 1801 s1 = " if ival_ <= 0:\n" 1802 outfile.write(s1) 1803 s1 = " raise ValueError('Invalid positiveInteger (%s)' % child_.toxml()))\n" 1804 outfile.write(s1) 1805 if childType == NonPositiveIntegerType: 1806 s1 = " if ival_ > 0:\n" 1807 outfile.write(s1) 1808 s1 = " raise ValueError('Invalid nonPositiveInteger (%s)' % child_.toxml()))\n" 1809 outfile.write(s1) 1810 if childType == NegativeIntegerType: 1811 s1 = " if ival_ >= 0:\n" 1812 outfile.write(s1) 1813 s1 = " raise ValueError('Invalid negativeInteger (%s)' % child_.toxml()))\n" 1814 outfile.write(s1) 1815 if childType == NonNegativeIntegerType: 1816 s1 = " if ival_ < 0:\n" 1817 outfile.write(s1) 1818 s1 = " raise ValueError('Invalid nonNegativeInteger (%s)' % child_.toxml()))\n" 1819 outfile.write(s1) 1820 s1 = " else:\n" 1821 outfile.write(s1) 1822 s1 = " ival_ = -1\n" 1823 outfile.write(s1) 1824 s1 = " obj_ = self.mixedclass_(MixedContainer.CategorySimple,\n" 1825 outfile.write(s1) 1826 s1 = " MixedContainer.TypeInteger, '%s', ival_)\n" % \ 1827 origName 1828 outfile.write(s1) 1829 s1 = " self.content_.append(obj_)\n" 1830 outfile.write(s1) 1831 elif childType == BooleanType: 1832 s1 = " %s child_.nodeType == Node.ELEMENT_NODE and \\\n" % \ 1833 keyword 1834 outfile.write(s1) 1835 s1 = " nodeName_ == '%s':\n" % origName 1836 outfile.write(s1) 1837 s1 = " if child_.firstChild:\n" 1838 outfile.write(s1) 1839 s1 = " sval_ = child_.firstChild.nodeValue\n" 1840 outfile.write(s1) 1841 s1 = " if sval_ in ('true', '1'):\n" 1842 outfile.write(s1) 1843 s1 = " ival_ = 1\n" 1844 outfile.write(s1) 1845 s1 = " elif sval_ in ('false', '0'):\n" 1846 outfile.write(s1) 1847 s1 = " ival_ = 0\n" 1848 outfile.write(s1) 1849 s1 = " else:\n" 1850 outfile.write(s1) 1851 s1 = " raise ValueError('requires boolean -- %s' % child_.toxml())\n" 1852 outfile.write(s1) 1853 s1 = " obj_ = self.mixedclass_(MixedContainer.CategorySimple,\n" 1854 outfile.write(s1) 1855 s1 = " MixedContainer.TypeInteger, '%s', ival_)\n" % \ 1856 origName 1857 outfile.write(s1) 1858 s1 = " self.content_.append(obj_)\n" 1859 outfile.write(s1) 1860 elif childType == FloatType or \ 1861 childType == DoubleType or \ 1862 childType == DecimalType: 1863 s1 = " %s child_.nodeType == Node.ELEMENT_NODE and \\\n" % \ 1864 keyword 1865 outfile.write(s1) 1866 s1 = " nodeName_ == '%s':\n" % origName 1867 outfile.write(s1) 1868 s1 = " if child_.firstChild:\n" 1869 outfile.write(s1) 1870 s1 = " sval_ = child_.firstChild.nodeValue\n" 1871 outfile.write(s1) 1872 s1 = " try:\n" 1873 outfile.write(s1) 1874 s1 = " fval_ = float(sval_)\n" 1875 outfile.write(s1) 1876 s1 = " except ValueError:\n" 1877 outfile.write(s1) 1878 s1 = " raise ValueError('requires float (or double) -- %s' % child_.toxml())\n" 1879 outfile.write(s1) 1880 s1 = " obj_ = self.mixedclass_(MixedContainer.CategorySimple,\n" 1881 outfile.write(s1) 1882 s1 = " MixedContainer.TypeFloat, '%s', fval_)\n" % \ 1883 origName 1884 outfile.write(s1) 1885 s1 = " self.content_.append(obj_)\n" 1886 outfile.write(s1) 1887 else: 1888 # Perhaps it's a complexType that is defined right here. 1889 # Generate (later) a class for the nested types. 1890 if not delayed and not child in DelayedElements: 1891 DelayedElements.append(child) 1892 DelayedElements_subclass.append(child) 1893 s1 = " %s child_.nodeType == Node.ELEMENT_NODE and \\\n" % \ 1894 keyword 1895 outfile.write(s1) 1896 s1 = " nodeName_ == '%s':\n" % origName 1897 outfile.write(s1) 1898 s1 = " childobj_ = %s%s.factory()\n" % \ 1899 (prefix, cleanupName(mapName(childType))) 1900 outfile.write(s1) 1901 s1 = " childobj_.build(child_)\n" 1902 outfile.write(s1) 1903 s1 = " obj_ = self.mixedclass_(MixedContainer.CategoryComplex,\n" 1904 outfile.write(s1) 1905 s1 = " MixedContainer.TypeNone, '%s', childobj_)\n" % \ 1906 origName 1907 outfile.write(s1) 1908 s1 = " self.content_.append(obj_)\n" 1909 outfile.write(s1)
1910 1911
1912 -def generateBuildMixed(outfile, prefix, element, keyword, delayed, hasChildren):
1913 for child in element.getChildren(): 1914 generateBuildMixed_1(outfile, prefix, child, child, keyword, delayed) 1915 hasChildren += 1 1916 keyword = 'elif' 1917 # Does this element have a substitutionGroup? 1918 # If so generate a clause for each element in the substitutionGroup. 1919 if child.getName() in SubstitutionGroups: 1920 for memberName in SubstitutionGroups[child.getName()]: 1921 if memberName in ElementDict: 1922 member = ElementDict[memberName] 1923 generateBuildMixed_1(outfile, prefix, member, child, 1924 keyword, delayed) 1925 s1 = " %s child_.nodeType == Node.TEXT_NODE:\n" % keyword 1926 outfile.write(s1) 1927 s1 = " obj_ = self.mixedclass_(MixedContainer.CategoryText,\n" 1928 outfile.write(s1) 1929 s1 = " MixedContainer.TypeNone, '', child_.nodeValue)\n" 1930 outfile.write(s1) 1931 s1 = " self.content_.append(obj_)\n" 1932 outfile.write(s1) 1933 ## base = element.getBase() 1934 ## if base and base in ElementDict: 1935 ## parent = ElementDict[base] 1936 ## hasChildren = generateBuildMixed(outfile, prefix, parent, keyword, delayed, hasChildren) 1937 return hasChildren
1938 1939
1940 -def generateBuildStandard_1(outfile, prefix, child, headChild, keyword, delayed):
1941 global DelayedElements, DelayedElements_subclass 1942 origName = child.getName() 1943 name = cleanupName(child.getName()) 1944 mappedName = mapName(name) 1945 headName = cleanupName(headChild.getName()) 1946 attrCount = len(child.getAttributeDefs()) 1947 childType = child.getType() 1948 if attrCount == 0 and \ 1949 (childType in StringType or \ 1950 childType == TokenType or \ 1951 childType == DateTimeType or \ 1952 childType == DateType \ 1953 ): 1954 s1 = ' %s child_.nodeType == Node.ELEMENT_NODE and \\\n' % \ 1955 keyword 1956 outfile.write(s1) 1957 s1 = " nodeName_ == '%s':\n" % origName 1958 outfile.write(s1) 1959 s1 = " %s_ = ''\n" % name 1960 outfile.write(s1) 1961 s1 = " for text__content_ in child_.childNodes:\n" 1962 outfile.write(s1) 1963 s1 = " %s_ += text__content_.nodeValue\n" % name 1964 outfile.write(s1) 1965 if childType == TokenType: 1966 s1 = " %s_ = ' '.join(%s_.split())\n" % (name, name,) 1967 outfile.write(s1) 1968 if child.getMaxOccurs() > 1: 1969 s1 = " self.%s.append(%s_)\n" % (mappedName, name,) 1970 outfile.write(s1) 1971 else: 1972 s1 = " self.%s = %s_\n" % (mappedName, name,) 1973 outfile.write(s1) 1974 elif childType in IntegerType or \ 1975 childType == PositiveIntegerType or \ 1976 childType == NonPositiveIntegerType or \ 1977 childType == NegativeIntegerType or \ 1978 childType == NonNegativeIntegerType: 1979 s1 = " %s child_.nodeType == Node.ELEMENT_NODE and \\\n" % \ 1980 keyword 1981 outfile.write(s1) 1982 s1 = " nodeName_ == '%s':\n" % origName 1983 outfile.write(s1) 1984 s1 = " if child_.firstChild:\n" 1985 outfile.write(s1) 1986 s1 = " sval_ = child_.firstChild.nodeValue\n" 1987 outfile.write(s1) 1988 s1 = " try:\n" 1989 outfile.write(s1) 1990 s1 = " ival_ = int(sval_)\n" 1991 outfile.write(s1) 1992 s1 = " except ValueError:\n" 1993 outfile.write(s1) 1994 s1 = " raise ValueError('requires integer -- %s' % child_.toxml())\n" 1995 outfile.write(s1) 1996 if childType == PositiveIntegerType: 1997 s1 = " if ival_ <= 0:\n" 1998 outfile.write(s1) 1999 s1 = " raise ValueError('requires positiveInteger -- %s' % child_.toxml())\n" 2000 outfile.write(s1) 2001 elif childType == NonPositiveIntegerType: 2002 s1 = " if ival_ > 0:\n" 2003 outfile.write(s1) 2004 s1 = " raise ValueError('requires nonPositiveInteger -- %s' % child_.toxml())\n" 2005 outfile.write(s1) 2006 elif childType == NegativeIntegerType: 2007 s1 = " if ival_ >= 0:\n" 2008 outfile.write(s1) 2009 s1 = " raise ValueError('requires negativeInteger -- %s' % child_.toxml())\n" 2010 outfile.write(s1) 2011 elif childType == NonNegativeIntegerType: 2012 s1 = " if ival_ < 0:\n" 2013 outfile.write(s1) 2014 s1 = " raise ValueError('requires nonNegativeInteger -- %s' % child_.toxml())\n" 2015 outfile.write(s1) 2016 if child.getMaxOccurs() > 1: 2017 s1 = " self.%s.append(ival_)\n" % (mappedName,) 2018 outfile.write(s1) 2019 else: 2020 s1 = " self.%s = ival_\n" % (mappedName,) 2021 outfile.write(s1) 2022 elif childType == BooleanType: 2023 s1 = " %s child_.nodeType == Node.ELEMENT_NODE and \\\n" % \ 2024 keyword 2025 outfile.write(s1) 2026 s1 = " nodeName_ == '%s':\n" % origName 2027 outfile.write(s1) 2028 s1 = " if child_.firstChild:\n" 2029 outfile.write(s1) 2030 s1 = " sval_ = child_.firstChild.nodeValue\n" 2031 outfile.write(s1) 2032 s1 = " if sval_ in ('true', '1'):\n" 2033 outfile.write(s1) 2034 s1 = " ival_ = 1\n" 2035 outfile.write(s1) 2036 s1 = " elif sval_ in ('false', '0'):\n" 2037 outfile.write(s1) 2038 s1 = " ival_ = 0\n" 2039 outfile.write(s1) 2040 s1 = " else:\n" 2041 outfile.write(s1) 2042 s1 = " raise ValueError('requires boolean -- %s' % child_.toxml())\n" 2043 outfile.write(s1) 2044 if child.getMaxOccurs() > 1: 2045 s1 = " self.%s.append(ival_)\n" % (mappedName,) 2046 outfile.write(s1) 2047 else: 2048 s1 = " self.%s = ival_\n" % (mappedName,) 2049 outfile.write(s1) 2050 elif childType == FloatType or \ 2051 childType == DoubleType or \ 2052 childType == DecimalType: 2053 s1 = " %s child_.nodeType == Node.ELEMENT_NODE and \\\n" % \ 2054 keyword 2055 outfile.write(s1) 2056 s1 = " nodeName_ == '%s':\n" % origName 2057 outfile.write(s1) 2058 s1 = " if child_.firstChild:\n" 2059 outfile.write(s1) 2060 s1 = " sval_ = child_.firstChild.nodeValue\n" 2061 outfile.write(s1) 2062 s1 = " try:\n" 2063 outfile.write(s1) 2064 s1 = " fval_ = float(sval_)\n" 2065 outfile.write(s1) 2066 s1 = " except ValueError:\n" 2067 outfile.write(s1) 2068 s1 = " raise ValueError('requires float (or double) -- %s' % child_.toxml())\n" 2069 outfile.write(s1) 2070 if child.getMaxOccurs() > 1: 2071 s1 = " self.%s.append(fval_)\n" % (mappedName,) 2072 outfile.write(s1) 2073 else: 2074 s1 = " self.%s = fval_\n" % (mappedName,) 2075 outfile.write(s1) 2076 else: 2077 # Perhaps it's a complexType that is defined right here. 2078 # Generate (later) a class for the nested types. 2079 if not delayed and not child in DelayedElements: 2080 DelayedElements.append(child) 2081 DelayedElements_subclass.append(child) 2082 s1 = " %s child_.nodeType == Node.ELEMENT_NODE and \\\n" % \ 2083 keyword 2084 outfile.write(s1) 2085 s1 = " nodeName_ == '%s':\n" % origName 2086 outfile.write(s1) 2087 s1 = " obj_ = %s%s.factory()\n" % \ 2088 (prefix, cleanupName(mapName(childType))) 2089 outfile.write(s1) 2090 s1 = " obj_.build(child_)\n" 2091 outfile.write(s1) 2092 if headChild.getMaxOccurs() > 1: 2093 s1 = " self.%s.append(obj_)\n" % headName 2094 outfile.write(s1) 2095 else: 2096 s1 = " self.set%s(obj_)\n" % make_gs_name(headName) 2097 outfile.write(s1) 2098 # 2099 # If this child is defined in a simpleType, then generate 2100 # a validator method. 2101 typeName = None 2102 if child.getSimpleType(): 2103 typeName = child.getSimpleType() 2104 elif (childType in ElementDict and 2105 ElementDict[childType].getSimpleType()): 2106 typeName = ElementDict[childType].getType() 2107 if typeName: 2108 s1 = " self.validate_%s(self.%s) # validate type %s\n" % ( 2109 typeName, mappedName, typeName,) 2110 outfile.write(s1)
2111 2112
2113 -def generateBuildStandard(outfile, prefix, element, keyword, delayed, hasChildren):
2114 for child in element.getChildren(): 2115 generateBuildStandard_1(outfile, prefix, child, child, keyword, delayed) 2116 hasChildren += 1 2117 keyword = 'elif' 2118 # Does this element have a substitutionGroup? 2119 # If so generate a clause for each element in the substitutionGroup. 2120 childName = child.getName() 2121 if childName in SubstitutionGroups: 2122 for memberName in SubstitutionGroups[childName]: 2123 memberName = cleanupName(memberName) 2124 if memberName in ElementDict: 2125 member = ElementDict[memberName] 2126 generateBuildStandard_1(outfile, prefix, member, child, 2127 keyword, delayed) 2128 return hasChildren
2129 2130
2131 -def generateBuildFn(outfile, prefix, element, delayed):
2132 base = element.getBase() 2133 outfile.write(' def build(self, node_):\n') 2134 outfile.write(' attrs = node_.attributes\n') 2135 outfile.write(' self.buildAttributes(attrs)\n') 2136 ## if len(element.getChildren()) > 0: 2137 childCount = countChildren(element, 0) 2138 if childCount == 0: 2139 s1 = " self.valueOf_ = ''\n" 2140 outfile.write(s1) 2141 outfile.write(' for child_ in node_.childNodes:\n') 2142 outfile.write(" nodeName_ = child_.nodeName.split(':')[-1]\n") 2143 outfile.write(" self.buildChildren(child_, nodeName_)\n") 2144 outfile.write(' def buildAttributes(self, attrs):\n') 2145 hasAttributes = generateBuildAttributes(outfile, element, 0) 2146 if base and base not in SimpleTypeDict: 2147 hasAttributes += 1 2148 s1 = ' %s.buildAttributes(self, attrs)\n' % (base,) 2149 outfile.write(s1) 2150 if hasAttributes == 0: 2151 outfile.write(' pass\n') 2152 outfile.write(' def buildChildren(self, child_, nodeName_):\n') 2153 keyword = 'if' 2154 hasChildren = 0 2155 if element.isMixed(): 2156 hasChildren = generateBuildMixed(outfile, prefix, element, keyword, 2157 delayed, hasChildren) 2158 else: # not element.isMixed() 2159 hasChildren = generateBuildStandard(outfile, prefix, element, keyword, 2160 delayed, hasChildren) 2161 if hasChildren == 0: 2162 ## s1 = " self.valueOf_ = ''\n" 2163 ## outfile.write(s1) 2164 ## s1 = " for child in child_.childNodes:\n" 2165 ## outfile.write(s1) 2166 ## s1 = " if child.nodeType == Node.TEXT_NODE:\n" 2167 ## outfile.write(s1) 2168 ## s1 = " self.valueOf_ += child.nodeValue\n" 2169 ## outfile.write(s1) 2170 s1 = " if child_.nodeType == Node.TEXT_NODE:\n" 2171 outfile.write(s1) 2172 s1 = " self.valueOf_ += child_.nodeValue\n" 2173 outfile.write(s1) 2174 if base and base in ElementDict and base not in SimpleTypeDict: 2175 parent = ElementDict[base] 2176 if len(parent.getChildren()) > 0: 2177 s1 = " %s.buildChildren(self, child_, nodeName_)\n" % (base,) 2178 outfile.write(s1)
2179 # end generateBuildFn 2180 2181
2182 -def countElementChildren(element, count):
2183 count += len(element.getChildren()) 2184 base = element.getBase() 2185 if base and base in ElementDict: 2186 parent = ElementDict[base] 2187 countElementChildren(parent, count) 2188 return count
2189 2190
2191 -def buildCtorArgs_multilevel(element):
2192 content = [] 2193 addedArgs = {} 2194 add = content.append 2195 buildCtorArgs_multilevel_aux(addedArgs, add, element) 2196 count = countElementChildren(element, 0) 2197 if count == 0: 2198 add(", valueOf_=''") 2199 if element.isMixed(): 2200 add(', mixedclass_=None') 2201 add(', content_=None') 2202 s1 = ''.join(content) 2203 return s1
2204 2205
2206 -def buildCtorArgs_multilevel_aux(addedArgs, add, element):
2207 base = element.getBase() 2208 if base and base in ElementDict: 2209 parent = ElementDict[base] 2210 buildCtorArgs_multilevel_aux(addedArgs, add, parent) 2211 buildCtorArgs_aux(addedArgs, add, element)
2212 2213
2214 -def buildCtorArgs_aux(addedArgs, add, element):
2215 attrDefs = element.getAttributeDefs() 2216 for key in attrDefs: 2217 attrDef = attrDefs[key] 2218 name = attrDef.getName() 2219 if name in addedArgs: 2220 continue 2221 addedArgs[name] = 1 2222 mappedName = name.replace(':', '_') 2223 mappedName = cleanupName(mapName(mappedName)) 2224 try: 2225 atype = attrDef.getData_type() 2226 except KeyError: 2227 atype = StringType 2228 if atype in StringType or \ 2229 atype == TokenType or \ 2230 atype == DateTimeType or \ 2231 atype == DateType: 2232 add(', %s=\'\'' % mappedName) 2233 elif atype in IntegerType: 2234 add(', %s=-1' % mappedName) 2235 elif atype == PositiveIntegerType: 2236 add(', %s=1' % mappedName) 2237 elif atype == NonPositiveIntegerType: 2238 add(', %s=0' % mappedName) 2239 elif atype == NegativeIntegerType: 2240 add(', %s=-1' % mappedName) 2241 elif atype == NonNegativeIntegerType: 2242 add(', %s=0' % mappedName) 2243 elif atype == BooleanType: 2244 add(', %s=0' % mappedName) 2245 elif atype == FloatType or atype == DoubleType or atype == DecimalType: 2246 add(', %s=0.0' % mappedName) 2247 else: 2248 add(', %s=None' % mappedName) 2249 nestedElements = 0 2250 for child in element.getChildren(): 2251 cleanName = child.getCleanName() 2252 if cleanName in addedArgs: 2253 continue 2254 addedArgs[cleanName] = 1 2255 nestedElements = 1 2256 if child.getMaxOccurs() > 1: 2257 add(', %s=None' % cleanName) 2258 else: 2259 childType = child.getType() 2260 if childType in StringType or \ 2261 childType == TokenType or \ 2262 childType == DateTimeType or \ 2263 childType == DateType: 2264 add(', %s=\'\'' % cleanName) 2265 elif childType in IntegerType: 2266 add(', %s=-1' % cleanName) 2267 elif childType == PositiveIntegerType: 2268 add(', %s=1' % cleanName) 2269 elif childType == NonPositiveIntegerType: 2270 add(', %s=0' % cleanName) 2271 elif childType == NegativeIntegerType: 2272 add(', %s=-1' % cleanName) 2273 elif childType == NonNegativeIntegerType: 2274 add(', %s=0' % cleanName) 2275 elif childType == BooleanType: 2276 add(', %s=0' % cleanName) 2277 elif childType == FloatType or \ 2278 childType == DoubleType or \ 2279 childType == DecimalType: 2280 add(', %s=0.0' % cleanName) 2281 else: 2282 add(', %s=None' % cleanName)
2283 # end buildCtorArgs_aux 2284 2285 2286 MixedCtorInitializers = '''\ 2287 if mixedclass_ is None: 2288 self.mixedclass_ = MixedContainer 2289 else: 2290 self.mixedclass_ = mixedclass_ 2291 if content_ is None: 2292 self.content_ = [] 2293 else: 2294 self.content_ = content_ 2295 ''' 2296 2297
2298 -def generateCtor(outfile, element):
2299 s2 = buildCtorArgs_multilevel(element) 2300 s1 = ' def __init__(self%s):\n' % s2 2301 outfile.write(s1) 2302 base = element.getBase() 2303 if base and base in ElementDict: 2304 parent = ElementDict[base] 2305 s2 = buildCtorParams(parent) 2306 s1 = ' %s.__init__(self%s)\n' % (base, s2,) 2307 outfile.write(s1) 2308 attrDefs = element.getAttributeDefs() 2309 for key in attrDefs: 2310 attrDef = attrDefs[key] 2311 mappedName = cleanupName(attrDef.getName()) 2312 mappedName = mapName(mappedName) 2313 logging.debug("Constructor attribute: %s" % mappedName) 2314 s1 = ' self.%s = %s\n' % (mappedName, mappedName) 2315 outfile.write(s1) 2316 member = 1 2317 # Generate member initializers in ctor. 2318 if element.isMixed(): 2319 outfile.write(MixedCtorInitializers) 2320 else: 2321 member = 0 2322 nestedElements = 0 2323 for child in element.getChildren(): 2324 name = cleanupName(child.getCleanName()) 2325 logging.debug("Constructor child: %s" % name) 2326 logging.debug("Dump: %s" % child.__dict__) 2327 if child.getMaxOccurs() > 1: 2328 s1 = ' if %s is None:\n' % (name,) 2329 outfile.write(s1) 2330 s1 = ' self.%s = []\n' % (name,) 2331 outfile.write(s1) 2332 s1 = ' else:\n' 2333 outfile.write(s1) 2334 s1 = ' self.%s = %s\n' % \ 2335 (name, name) 2336 outfile.write(s1) 2337 else: 2338 s1 = ' self.%s = %s\n' % \ 2339 (name, name) 2340 outfile.write(s1) 2341 member = 1 2342 nestedElements = 1 2343 if not nestedElements: 2344 s1 = ' self.valueOf_ = valueOf_\n' 2345 outfile.write(s1) 2346 member = 1 2347 if element.getAnyAttribute(): 2348 s1 = ' self.anyAttributes_ = {}\n' 2349 outfile.write(s1) 2350 member = 1 2351 if not member: 2352 outfile.write(' pass\n')
2353 # end generateCtor 2354 2355 # 2356 # Attempt to retrieve the body (implementation) of a validator 2357 # from a directory containing one file for each simpleType. 2358 # The name of the file should be the same as the name of the 2359 # simpleType with and optional ".py" extension.
2360 -def getValidatorBody(stName):
2361 retrieved = 0 2362 if ValidatorBodiesBasePath: 2363 found = 0 2364 path = '%s%s%s.py' % (ValidatorBodiesBasePath, os.sep, stName,) 2365 if os.path.exists(path): 2366 found = 1 2367 else: 2368 path = '%s%s%s' % (ValidatorBodiesBasePath, os.sep, stName,) 2369 if os.path.exists(path): 2370 found = 1 2371 if found: 2372 infile = open(path, 'r') 2373 lines = infile.readlines() 2374 infile.close() 2375 lines1 = [] 2376 for line in lines: 2377 if not line.startswith('##'): 2378 lines1.append(line) 2379 s1 = ''.join(lines1) 2380 retrieved = 1 2381 if not retrieved: 2382 s1 = ' pass\n' 2383 return s1
2384 2385 2386 # Generate get/set/add member functions.
2387 -def generateGettersAndSetters(outfile, element):
2388 nestedElements = 0 2389 generatedSimpleTypes = [] 2390 for child in element.getChildren(): 2391 name = cleanupName(child.getCleanName()) 2392 unmappedName = cleanupName(child.getName()) 2393 capName = make_gs_name(unmappedName) 2394 getMaxOccurs = child.getMaxOccurs() 2395 nestedElements = 1 2396 childType = child.getType() 2397 s1 = ' def get%s(self): return self.%s\n' % \ 2398 (capName, name) 2399 outfile.write(s1) 2400 s1 = ' def set%s(self, %s): self.%s = %s\n' % \ 2401 (capName, name, name, name) 2402 outfile.write(s1) 2403 if child.getMaxOccurs() > 1: 2404 s1 = ' def add%s(self, value): self.%s.append(value)\n' % \ 2405 (capName, name) 2406 outfile.write(s1) 2407 s1 = ' def insert%s(self, index, value): self.%s[index] = value\n' % \ 2408 (capName, name) 2409 outfile.write(s1) 2410 if GenerateProperties: 2411 s1 = ' %sProp = property(get%s, set%s)\n' % \ 2412 (unmappedName, capName, capName) 2413 outfile.write(s1) 2414 # 2415 # If this child is defined in a simpleType, then generate 2416 # a validator method. 2417 typeName = None 2418 if child.getSimpleType(): 2419 typeName = child.getSimpleType() 2420 elif (childType in ElementDict and 2421 ElementDict[childType].getSimpleType()): 2422 typeName = ElementDict[childType].getType() 2423 if typeName: 2424 generatedSimpleTypes.append(typeName) 2425 #s1 = ' def validate_%s(self, value):\n' % (capName, ) 2426 s1 = ' def validate_%s(self, value):\n' % (typeName,) 2427 outfile.write(s1) 2428 if typeName in SimpleTypeDict: 2429 stObj = SimpleTypeDict[typeName] 2430 s1 = ' # Validate type %s, a restriction on %s.\n' % ( 2431 typeName, stObj.getBase(),) 2432 outfile.write(s1) 2433 else: 2434 s1 = ' # validate type %s\n' % (typeName,) 2435 outfile.write(s1) 2436 s1 = getValidatorBody(typeName) 2437 outfile.write(s1) 2438 attrDefs = element.getAttributeDefs() 2439 for key in attrDefs: 2440 attrDef = attrDefs[key] 2441 name = cleanupName(attrDef.getName().replace(':', '_')) 2442 mappedName = mapName(name) 2443 capName = make_gs_name(mappedName) 2444 s1 = ' def get%s(self): return self.%s\n' % \ 2445 (make_gs_name(name), mappedName) 2446 outfile.write(s1) 2447 # 2448 # What? An attribute cannot occur multiple times on the same 2449 # element. No attribute is a list of values. Right? 2450 ## if element.getMaxOccurs() > 1: 2451 ## s1 = ' def add%s(self, %s): self.%s.append(%s)\n' % \ 2452 ## (capName, mappedName, mappedName, mappedName) 2453 ## outfile.write(s1) 2454 ## s1 = ' def set%s(self, %s, index): self.%s[index] = %s\n' % \ 2455 ## (make_gs_name(name), mappedName, mappedName, mappedName) 2456 ## outfile.write(s1) 2457 ## else: 2458 s1 = ' def set%s(self, %s): self.%s = %s\n' % \ 2459 (make_gs_name(name), mappedName, mappedName, mappedName) 2460 outfile.write(s1) 2461 if GenerateProperties: 2462 s1 = ' %sProp = property(get%s, set%s)\n' % \ 2463 (mappedName, capName, capName) 2464 outfile.write(s1) 2465 if not nestedElements: 2466 s1 = ' def getValueOf_(self): return self.valueOf_\n' 2467 outfile.write(s1) 2468 s1 = ' def setValueOf_(self, valueOf_): self.valueOf_ = valueOf_\n' 2469 outfile.write(s1) 2470 if element.getAnyAttribute(): 2471 s1 = ' def getAnyAttributes_(self): return self.anyAttributes_\n' 2472 outfile.write(s1) 2473 s1 = ' def setAnyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_\n' 2474 outfile.write(s1)
2475 # end generateGettersAndSetters 2476 2477 2478 # 2479 # Generate a class variable whose value is a list of tuples, one 2480 # tuple for each member data item of the class. 2481 # Each tuble has 3 elements: (1) member name, (2) member data type, 2482 # (3) container/list or not (maxoccurs > 1).
2483 -def generateMemberSpec(outfile, element):
2484 content = [' _member_data_items = ['] 2485 add = content.append 2486 for child in element.getChildren(): 2487 name = cleanupName(child.getCleanName()) 2488 item1 = name 2489 item2 = child.getType() 2490 if child.getMaxOccurs() > 1: 2491 item3 = 1 2492 else: 2493 item3 = 0 2494 #item = " ('%s', '%s', %d)," % (item1, item2, item3, ) 2495 item = " _MemberSpec('%s', '%s', %d)," % (item1, item2, item3,) 2496 add(item) 2497 add(' ]') 2498 s1 = '\n'.join(content) 2499 outfile.write(s1) 2500 outfile.write('\n')
2501 2502
2503 -def generateUserMethods(outfile, element):
2504 if not UserMethodsModule: 2505 return 2506 specs = UserMethodsModule.METHOD_SPECS 2507 name = cleanupName(element.getCleanName()) 2508 values_dict = {'class_name': name, } 2509 for spec in specs: 2510 if spec.match_name(name): 2511 source = spec.get_interpolated_source(values_dict) 2512 outfile.write(source)
2513 2514
2515 -def generateClasses(outfile, prefix, element, delayed):
2516 logging.debug("Generating class for: %s" % element) 2517 base = element.getBase() 2518 logging.debug("Element base: %s" % base) 2519 wrt = outfile.write 2520 ## if (not element.getChildren()) and (not element.getAttributeDefs()): 2521 ## return 2522 if not element.isExplicitDefine(): 2523 logging.debug("Not an explicit define, returning.") 2524 return 2525 # If this element is an extension (has a base) and the base has 2526 # not been generated, then postpone it. 2527 if base and base in ElementDict: 2528 parent = ElementDict[base] 2529 parentName = parent.getName() 2530 if (parentName not in AlreadyGenerated and 2531 parentName not in SimpleTypeDict.keys()): 2532 PostponedExtensions.append(element) 2533 return 2534 if element.getName() in AlreadyGenerated: 2535 return 2536 AlreadyGenerated.append(element.getName()) 2537 if element.getMixedExtensionError(): 2538 print '*** Element %s extension chain contains mixed and non-mixed content. Not generated.' % \ 2539 (element.getName(),) 2540 return 2541 ElementsForSubclasses.append(element) 2542 name = element.getCleanName() 2543 if GenerateProperties: 2544 if base and base not in SimpleTypeDict: 2545 s1 = 'class %s%s(object, %s):\n' % (prefix, name, base) 2546 else: 2547 s1 = 'class %s%s(object):\n' % (prefix, name) 2548 else: 2549 if base and base not in SimpleTypeDict: 2550 s1 = 'class %s%s(%s):\n' % (prefix, name, base) 2551 else: 2552 s1 = 'class %s%s:\n' % (prefix, name) 2553 wrt(s1) 2554 if UserMethodsModule: 2555 generateMemberSpec(outfile, element) 2556 wrt(' subclass = None\n') 2557 generateCtor(outfile, element) 2558 wrt(' def factory(*args_, **kwargs_):\n') 2559 wrt(' if %s%s.subclass:\n' % (prefix, name)) 2560 wrt(' return %s%s.subclass(*args_, **kwargs_)\n' % (prefix, name)) 2561 wrt(' else:\n') 2562 wrt(' return %s%s(*args_, **kwargs_)\n' % (prefix, name)) 2563 wrt(' factory = staticmethod(factory)\n') 2564 generateGettersAndSetters(outfile, element) 2565 generateExportFn(outfile, prefix, element) 2566 generateExportFnXML(outfile, prefix, element) 2567 generateStaticParseString(outfile, prefix, element) 2568 generateStaticParseFile(outfile, prefix, element) 2569 generateMarshal(outfile, prefix, element) 2570 generateExportLiteralFn(outfile, prefix, element) 2571 generateBuildFn(outfile, prefix, element, delayed) 2572 generateUserMethods(outfile, element) 2573 wrt('# end class %s\n' % name) 2574 wrt('\n\n')
2575 # end generateClasses 2576 2577 2578 # 2579 # Generate the SAX handler class for SAX parsing. 2580 # 2581 2582 SAX_STARTELEMENT_1 = """\ 2583 def startElement(self, name, attrs): 2584 done = 0 2585 if name == '%s': 2586 obj = %s.factory() 2587 stackObj = SaxStackElement('%s', obj) 2588 self.stack.append(stackObj) 2589 done = 1 2590 """ 2591 2592 SAX_STARTELEMENT_2 = """\ 2593 stackObj = SaxStackElement('%s', obj) 2594 self.stack.append(stackObj) 2595 done = 1 2596 """ 2597 2598 SAX_STARTELEMENT_3 = """\ 2599 stackObj = SaxStackElement('%s', None) 2600 self.stack.append(stackObj) 2601 done = 1 2602 """ 2603 2604 SAX_STARTELEMENT_4 = """\ 2605 if not done: 2606 self.reportError('"%s" element not allowed here.' % name) 2607 """ 2608 2609 SAX_ATTR_INTEGER = """\ 2610 val = attrs.get('%s', None) 2611 if val is not None: 2612 try: 2613 obj.set%s(int(val)) 2614 except Exception: 2615 self.reportError('"%s" attribute must be integer') 2616 """ 2617 2618 SAX_ATTR_BOOLEAN = """\ 2619 val = attrs.get('%s', None) 2620 if val is not None: 2621 if val in ('true', '1'): 2622 obj.set%s(1) 2623 elif val in ('false', '0'): 2624 obj.set%s(0) 2625 else: 2626 self.reportError('"%s" attribute must be boolean ("true", "1", "false", "0")') 2627 """ 2628 2629 SAX_ATTR_FLOAT = """\ 2630 val = attrs.get('%s', None) 2631 if val is not None: 2632 try: 2633 obj.set%s(float(val)) 2634 except Exception: 2635 self.reportError('"%s" attribute must be float') 2636 """ 2637 2638 SAX_ATTR_STRING = """\ 2639 val = attrs.get('%s', None) 2640 if val is not None: 2641 obj.set%s(val) 2642 """ 2643
2644 -def getClassName(element):
2645 name = element.getCleanName() 2646 return name
2647
2648 -def generateSaxAttributes(wrt, element):
2649 attrDefs = element.getAttributeDefs() 2650 for key in attrDefs: 2651 attrDef = attrDefs[key] 2652 name = attrDef.getName() 2653 atype = attrDef.getData_type() 2654 if atype in IntegerType: 2655 s1 = SAX_ATTR_INTEGER % (name, make_gs_name(name), name) 2656 wrt(s1) 2657 ## s1 = " if attrs.get('%s'):\n" % name 2658 ## wrt(s1) 2659 ## s1 = ' try:\n' 2660 ## wrt(s1) 2661 ## s1 = " self.%s = int(attrs.get('%s').value)\n" % \ 2662 ## (name, name) 2663 ## wrt(s1) 2664 ## s1 = ' except ValueError:\n' 2665 ## wrt(s1) 2666 ## s1 = " raise ValueError('Bad integer')\n" 2667 ## wrt(s1) 2668 elif atype == BooleanType: 2669 s1 = SAX_ATTR_BOOLEAN % (name, make_gs_name(name), \ 2670 make_gs_name(name), name) 2671 wrt(s1) 2672 ## wrt(s1) 2673 ## s1 = " if attrs.get('%s'):\n" % name 2674 ## wrt(s1) 2675 ## s1 = " if attrs.get('%s').value in ('true', '1'):\n" % \ 2676 ## name 2677 ## wrt(s1) 2678 ## s1 = " self.%s = 1\n" % \ 2679 ## name 2680 ## wrt(s1) 2681 ## s1 = " elif attrs.get('%s').value in ('false', '0'):\n" % \ 2682 ## name 2683 ## wrt(s1) 2684 ## s1 = " self.%s = 0\n" % \ 2685 ## name 2686 ## wrt(s1) 2687 ## s1 = ' else:\n' 2688 ## wrt(s1) 2689 ## s1 = " raise ValueError('Bad boolean')\n" 2690 ## wrt(s1) 2691 elif atype == FloatType or atype == DoubleType or atype == DecimalType: 2692 s1 = SAX_ATTR_FLOAT % (name, make_gs_name(name), name) 2693 wrt(s1) 2694 ## s1 = " if attrs.get('%s'):\n" % name 2695 ## wrt(s1) 2696 ## s1 = ' try:\n' 2697 ## wrt(s1) 2698 ## s1 = " self.%s = float(attrs.get('%s').value)\n" % \ 2699 ## (name, name) 2700 ## wrt(s1) 2701 ## s1 = ' except Exception:\n' 2702 ## wrt(s1) 2703 ## s1 = " raise ValueError('Bad float/double')\n" 2704 ## wrt(s1) 2705 else: 2706 # Assume attr['type'] in StringType or attr['type'] == DateTimeType: 2707 s1 = SAX_ATTR_STRING % (name, make_gs_name(name)) 2708 wrt(s1)
2709 ## s1 = " if attrs.get('%s'):\n" % name 2710 ## wrt(s1) 2711 ## s1 = " self.%s = attrs.get('%s').value\n" % (name, name) 2712 ## wrt(s1) 2713 2714
2715 -def generateSAXStartElement_1(wrt, element):
2716 origName = element.getName() 2717 typeName = cleanupName(mapName(element.getRawType())) 2718 className = element.getCleanName() 2719 s1 = " elif name == '%s':\n" % origName 2720 wrt(s1) 2721 if element.isComplex(): 2722 s1 = " obj = %s.factory()\n" % cleanupName(typeName) 2723 wrt(s1) 2724 element1 = SaxElementDict[element.getCleanName()] 2725 generateSaxAttributes(wrt, element1) 2726 if element.isComplex(): 2727 s1 = SAX_STARTELEMENT_2 % className 2728 else: 2729 s1 = SAX_STARTELEMENT_3 % className 2730 wrt(s1)
2731
2732 -def generateSAXStartElement(outfile, root, elementList):
2733 wrt = outfile.write 2734 name = root.getChildren()[0].getName() 2735 s1 = SAX_STARTELEMENT_1 % (name, name, name) 2736 wrt(s1) 2737 for element, parent in elementList: 2738 generateSAXStartElement_1(wrt, element) 2739 s1 = SAX_STARTELEMENT_4 2740 wrt(s1) 2741 wrt('\n')
2742 2743 2744 SAX_ENDELEMENT_1 = """\ 2745 if name == '%s': 2746 if len(self.stack) == 1: 2747 self.root = self.stack[-1].obj 2748 self.stack.pop() 2749 done = 1 2750 """ 2751 2752 SAX_ENDELEMENT_2 = """\ 2753 elif name == '%s': 2754 if len(self.stack) >= 2: 2755 self.stack[-2].obj.%s%s(self.stack[-1].obj) 2756 self.stack.pop() 2757 done = 1 2758 """ 2759 2760 SAX_ENDELEMENT_3 = """\ 2761 elif name == '%s': 2762 if len(self.stack) >= 2: 2763 content = self.stack[-1].content 2764 %s self.stack[-2].obj.%s%s(content) 2765 self.stack.pop() 2766 done = 1 2767 """ 2768 2769 SAX_ENDELEMENT_INT = """\ 2770 if content: 2771 try: 2772 content = int(content) 2773 except Exception: 2774 self.reportError('"%s" must be integer -- content: %%s' %% content) 2775 else: 2776 content = -1 2777 """ 2778 2779 SAX_ENDELEMENT_FLOAT = """\ 2780 if content: 2781 try: 2782 content = float(content) 2783 except Exception: 2784 self.reportError('"%s" must be float -- content: %%s' %% content) 2785 else: 2786 content = -1 2787 """ 2788 2789 SAX_ENDELEMENT_BOOLEAN = """\ 2790 if content and content in ('true', '1'): 2791 content = 1 2792 else: 2793 content = 0 2794 """ 2795 2796 SAX_ENDELEMENT_4 = """\ 2797 if not done: 2798 self.reportError('"%s" element not allowed here.' % name) 2799 """ 2800
2801 -def generateParentCheck(parent):
2802 s1 = "self.stack[-2].name == '%s'" % getClassName(parent) 2803 return s1
2804 ## strList = [] 2805 ## for parent in parentList: 2806 ## strList.append("self.stack[-2].name == '%s'" % \ 2807 ## parent.getName()) 2808 ## s1 = ' or '.join(strList) 2809 ## if len(parentList) > 1: 2810 ## s1 = '(%s)' % s1 2811 ## return s1 2812
2813 -def generateSAXEndElement(outfile, root, elementList):
2814 wrt = outfile.write 2815 s1 = " def endElement(self, name):\n" 2816 wrt(s1) 2817 s1 = " done = 0\n" 2818 wrt(s1) 2819 name = root.getChildren()[0].getName() 2820 s1 = SAX_ENDELEMENT_1 % (name,) 2821 wrt(s1) 2822 for element, parent in elementList: 2823 #s2 = generateParentCheck(parent) 2824 name = element.getName() 2825 capName = make_gs_name(element.getUnmappedCleanName()) 2826 if element.isComplex(): 2827 if element.getMaxOccurs() > 1: 2828 s1 = SAX_ENDELEMENT_2 % (name, 'add', capName) 2829 else: 2830 s1 = SAX_ENDELEMENT_2 % (name, 'set', capName) 2831 else: 2832 etype = element.getType() 2833 if etype in IntegerType: 2834 s3 = SAX_ENDELEMENT_INT % name 2835 elif etype == FloatType or etype == DoubleType or etype == DecimalType: 2836 s3 = SAX_ENDELEMENT_FLOAT % name 2837 elif etype == BooleanType: 2838 s3 = SAX_ENDELEMENT_BOOLEAN 2839 else: 2840 s3 = '' 2841 if element.getMaxOccurs() > 1: 2842 s1 = SAX_ENDELEMENT_3 % (name, s3, 'add', capName) 2843 else: 2844 s1 = SAX_ENDELEMENT_3 % (name, s3, 'set', capName) 2845 wrt(s1) 2846 s1 = SAX_ENDELEMENT_4 2847 wrt(s1) 2848 wrt('\n')
2849 2850 2851 SAX_HEADER = """\ 2852 from xml.sax import handler, make_parser 2853 2854 class SaxStackElement: 2855 def __init__(self, name='', obj=None): 2856 self.name = name 2857 self.obj = obj 2858 self.content = '' 2859 2860 # 2861 # SAX handler 2862 # 2863 class Sax%sHandler(handler.ContentHandler): 2864 def __init__(self): 2865 self.stack = [] 2866 self.root = None 2867 2868 def getRoot(self): 2869 return self.root 2870 2871 def setDocumentLocator(self, locator): 2872 self.locator = locator 2873 2874 def showError(self, msg): 2875 print '*** (showError):', msg 2876 sys.exit(-1) 2877 2878 """ 2879 2880 SAX_FOOTER = """\ 2881 def characters(self, chrs, start, end): 2882 if len(self.stack) > 0: 2883 self.stack[-1].content += chrs[start:end] 2884 2885 def reportError(self, mesg): 2886 locator = self.locator 2887 sys.stderr.write('Doc: %s Line: %d Column: %d\\n' % \\ 2888 (locator.getSystemId(), locator.getLineNumber(), 2889 locator.getColumnNumber() + 1)) 2890 sys.stderr.write(mesg) 2891 sys.stderr.write('\\n') 2892 sys.exit(-1) 2893 #raise RuntimeError 2894 2895 """ 2896 2897 2898 ##def produceAllElements(element, parent): 2899 ## if element.getType() in StringType or \ 2900 ## element.getType() in IntegerType or \ 2901 ## element.getType() == DecimalType or \ 2902 ## element.getType() == FloatType or \ 2903 ## element.getType() == DoubleType or \ 2904 ## element.getType() == BooleanType or \ 2905 ## len(element.getChildren()) != 0: 2906 ## yield (element, parent) 2907 ## for child in element.getChildren(): 2908 ## for element1, parent1 in produceAllElements(child, element): 2909 ## yield (element1, parent1) 2910 2911 2912 # 2913 # This version of produceAllElements does not use 'yield' and is, 2914 # therefore, usable with older versions of Python.
2915 -def produceAllElements_nogen(element, parent, collection):
2916 collection.append((element, parent)) 2917 for child in element.getChildren(): 2918 produceAllElements_nogen(child, element, collection)
2919 2920
2921 -def generateSAXHndlr(outfile, root):
2922 firstElement = root.getChildren()[0] 2923 name = firstElement.getName() 2924 s1 = SAX_HEADER % cleanupName(make_gs_name(name)) 2925 outfile.write(s1) 2926 elementList = [] 2927 collection = [] 2928 produceAllElements_nogen(root, None, collection) 2929 for element, parent in collection: 2930 if element == root: 2931 continue 2932 elementList.append((element, parent)) 2933 ## print '(gsh) element: %s/%s/%d parent: %s/%s/%d' % \ 2934 ## (element.getUnmappedCleanName(), element.getType(), id(element), 2935 ## #(element.getName(), element.getType(), id(element), 2936 ## parent.getName(), parent.getType(), id(parent)) 2937 ## if parent.getName() == 'booster': 2938 ## ipshell('at booster -- Entering ipshell.\\nHit Ctrl-D to exit') 2939 ## if element in elementDict: 2940 ## elementDict[element].append(parent) 2941 ## else: 2942 ## elementDict[element] = [parent] 2943 elementList1 = [] 2944 alreadySeen = [] 2945 for element, parent in elementList: 2946 if parent == root: 2947 continue 2948 if element.getName() in alreadySeen: 2949 continue 2950 alreadySeen.append(element.getName()) 2951 elementList1.append((element, parent)) 2952 ## print '+' * 20 2953 ## for element, parent in elementList1: 2954 ## print '(gsh) element: %s/%s/%d parent: %s/%s/%d' % \ 2955 ## (element.getUnmappedCleanName(), element.getType(), id(element), 2956 ## #(element.getName(), element.getType(), id(element), 2957 ## parent.getName(), parent.getType(), id(parent)) 2958 generateSAXStartElement(outfile, root, elementList1) 2959 generateSAXEndElement(outfile, root, elementList1) 2960 s1 = SAX_FOOTER 2961 outfile.write(s1)
2962 2963
2964 -def collect(element, elements):
2965 if element.getName() != 'root': 2966 elements.append(element) 2967 for child in element.getChildren(): 2968 collect(child, elements)
2969 2970 2971 TEMPLATE_HEADER = """\ 2972 #!/usr/bin/env python 2973 2974 # 2975 # Generated %s by EDGenerateDS.py. 2976 # 2977 2978 import sys 2979 import getopt 2980 import StringIO 2981 from xml.dom import minidom 2982 from xml.dom import Node 2983 2984 # 2985 # If you have installed IPython you can uncomment and use the following. 2986 # IPython is available from http://ipython.scipy.org/. 2987 # 2988 2989 ## from IPython.Shell import IPShellEmbed 2990 ## args = '' 2991 ## ipshell = IPShellEmbed(args, 2992 ## banner = 'Dropping into IPython', 2993 ## exit_msg = 'Leaving Interpreter, back to program.') 2994 2995 # Then use the following line where and when you want to drop into the 2996 # IPython shell: 2997 # ipshell('<some message> -- Entering ipshell.\\nHit Ctrl-D to exit') 2998 2999 # 3000 # Support/utility functions. 3001 # 3002 3003 def showIndent(outfile, level): 3004 for idx in range(level): 3005 outfile.write(' ') 3006 3007 def quote_xml(inStr): 3008 s1 = inStr 3009 s1 = s1.replace('&', '&amp;') 3010 s1 = s1.replace('<', '&lt;') 3011 s1 = s1.replace('"', '&quot;') 3012 return s1 3013 3014 def quote_python(inStr): 3015 s1 = inStr 3016 if s1.find("'") == -1: 3017 if s1.find('\\n') == -1: 3018 return "'%%s'" %% s1 3019 else: 3020 return "'''%%s'''" %% s1 3021 else: 3022 if s1.find('"') != -1: 3023 s1 = s1.replace('"', '\\\\"') 3024 if s1.find('\\n') == -1: 3025 return '"%%s"' %% s1 3026 else: 3027 return '\"\"\"%%s\"\"\"' %% s1 3028 3029 3030 class MixedContainer: 3031 # Constants for category: 3032 CategoryNone = 0 3033 CategoryText = 1 3034 CategorySimple = 2 3035 CategoryComplex = 3 3036 # Constants for content_type: 3037 TypeNone = 0 3038 TypeText = 1 3039 TypeString = 2 3040 TypeInteger = 3 3041 TypeFloat = 4 3042 TypeDecimal = 5 3043 TypeDouble = 6 3044 TypeBoolean = 7 3045 def __init__(self, category, content_type, name, value): 3046 self.category = category 3047 self.content_type = content_type 3048 self.name = name 3049 self.value = value 3050 def getCategory(self): 3051 return self.category 3052 def getContenttype(self, content_type): 3053 return self.content_type 3054 def getValue(self): 3055 return self.value 3056 def getName(self): 3057 return self.name 3058 def export(self, outfile, level, name): 3059 if self.category == MixedContainer.CategoryText: 3060 outfile.write(self.value) 3061 elif self.category == MixedContainer.CategorySimple: 3062 self.exportSimple(outfile, level, name) 3063 else: # category == MixedContainer.CategoryComplex 3064 self.value.export(outfile, level, name) 3065 def exportSimple(self, outfile, level, name): 3066 if self.content_type == MixedContainer.TypeString: 3067 outfile.write('<%%s>%%s</%%s>' %% (self.name, self.value, self.name)) 3068 elif self.content_type == MixedContainer.TypeInteger or \\ 3069 self.content_type == MixedContainer.TypeBoolean: 3070 outfile.write('<%%s>%%d</%%s>' %% (self.name, self.value, self.name)) 3071 elif self.content_type == MixedContainer.TypeFloat or \\ 3072 self.content_type == MixedContainer.TypeDecimal: 3073 outfile.write('<%%s>%%f</%%s>' %% (self.name, self.value, self.name)) 3074 elif self.content_type == MixedContainer.TypeDouble: 3075 outfile.write('<%%s>%%g</%%s>' %% (self.name, self.value, self.name)) 3076 def exportLiteral(self, outfile, level, name): 3077 if self.category == MixedContainer.CategoryText: 3078 showIndent(outfile, level) 3079 outfile.write('MixedContainer(%%d, %%d, "%%s", "%%s"),\\n' %% \\ 3080 (self.category, self.content_type, self.name, self.value)) 3081 elif self.category == MixedContainer.CategorySimple: 3082 showIndent(outfile, level) 3083 outfile.write('MixedContainer(%%d, %%d, "%%s", "%%s"),\\n' %% \\ 3084 (self.category, self.content_type, self.name, self.value)) 3085 else: # category == MixedContainer.CategoryComplex 3086 showIndent(outfile, level) 3087 outfile.write('MixedContainer(%%d, %%d, "%%s",\\n' %% \\ 3088 (self.category, self.content_type, self.name,)) 3089 self.value.exportLiteral(outfile, level + 1) 3090 showIndent(outfile, level) 3091 outfile.write(')\\n') 3092 3093 3094 class _MemberSpec(object): 3095 def __init__(self, name='', data_type='', container=0): 3096 self.name = name 3097 self.data_type = data_type 3098 self.container = container 3099 def set_name(self, name): self.name = name 3100 def get_name(self): return self.name 3101 def set_data_type(self, data_type): self.data_type = data_type 3102 def get_data_type(self): return self.data_type 3103 def set_container(self, container): self.container = container 3104 def get_container(self): return self.container 3105 3106 3107 # 3108 # Data representation classes. 3109 # 3110 3111 """ 3112 3113 # Fool (and straighten out) the syntax highlighting. 3114 # DUMMY = ''' 3115
3116 -def generateHeader(outfile, prefix):
3117 s1 = TEMPLATE_HEADER % time.ctime() 3118 outfile.write(s1)
3119 3120 3121 TEMPLATE_MAIN = """\ 3122 USAGE_TEXT = \"\"\" 3123 Usage: python <%(prefix)sParser>.py [ -s ] <in_xml_file> 3124 Options: 3125 -s Use the SAX parser, not the minidom parser. 3126 \"\"\" 3127 3128 def usage(): 3129 print USAGE_TEXT 3130 sys.exit(-1) 3131 3132 3133 # 3134 # SAX handler used to determine the top level element. 3135 # 3136 class SaxSelectorHandler(handler.ContentHandler): 3137 def __init__(self): 3138 self.topElementName = None 3139 def getTopElementName(self): 3140 return self.topElementName 3141 def startElement(self, name, attrs): 3142 self.topElementName = name 3143 raise StopIteration 3144 3145 3146 def parseSelect(inFileName): 3147 infile = file(inFileName, 'r') 3148 topElementName = None 3149 parser = make_parser() 3150 documentHandler = SaxSelectorHandler() 3151 parser.setContentHandler(documentHandler) 3152 try: 3153 try: 3154 parser.parse(infile) 3155 except StopIteration: 3156 topElementName = documentHandler.getTopElementName() 3157 if topElementName is None: 3158 raise RuntimeError, 'no top level element' 3159 topElementName = topElementName.replace('-', '_').replace(':', '_') 3160 if topElementName not in globals(): 3161 raise RuntimeError, 'no class for top element: %%s' %% topElementName 3162 topElement = globals()[topElementName] 3163 infile.seek(0) 3164 doc = minidom.parse(infile) 3165 finally: 3166 infile.close() 3167 rootNode = doc.childNodes[0] 3168 rootObj = topElement.factory() 3169 rootObj.build(rootNode) 3170 # Enable Python to collect the space used by the DOM. 3171 doc = None 3172 sys.stdout.write('<?xml version="1.0" ?>\\n') 3173 rootObj.export(sys.stdout, 0) 3174 return rootObj 3175 3176 3177 def saxParse(inFileName): 3178 parser = make_parser() 3179 documentHandler = Sax%(cap_name)sHandler() 3180 parser.setDocumentHandler(documentHandler) 3181 parser.parse('file:%%s' %% inFileName) 3182 root = documentHandler.getRoot() 3183 sys.stdout.write('<?xml version="1.0" ?>\\n') 3184 root.export(sys.stdout, 0) 3185 return root 3186 3187 3188 def saxParseString(inString): 3189 parser = make_parser() 3190 documentHandler = Sax%(cap_name)sHandler() 3191 parser.setDocumentHandler(documentHandler) 3192 parser.feed(inString) 3193 parser.close() 3194 rootObj = documentHandler.getRoot() 3195 #sys.stdout.write('<?xml version="1.0" ?>\\n') 3196 #rootObj.export(sys.stdout, 0) 3197 return rootObj 3198 3199 3200 def parse(inFileName): 3201 doc = minidom.parse(inFileName) 3202 rootNode = doc.documentElement 3203 rootObj = %(prefix)s%(root)s.factory() 3204 rootObj.build(rootNode) 3205 # Enable Python to collect the space used by the DOM. 3206 doc = None 3207 sys.stdout.write('<?xml version="1.0" ?>\\n') 3208 rootObj.export(sys.stdout, 0, name_="%(name)s") 3209 return rootObj 3210 3211 3212 def parseString(inString): 3213 doc = minidom.parseString(inString) 3214 rootNode = doc.documentElement 3215 rootObj = %(prefix)s%(root)s.factory() 3216 rootObj.build(rootNode) 3217 # Enable Python to collect the space used by the DOM. 3218 doc = None 3219 sys.stdout.write('<?xml version="1.0" ?>\\n') 3220 rootObj.export(sys.stdout, 0, name_="%(name)s") 3221 return rootObj 3222 3223 3224 def parseLiteral(inFileName): 3225 doc = minidom.parse(inFileName) 3226 rootNode = doc.documentElement 3227 rootObj = %(prefix)s%(root)s.factory() 3228 rootObj.build(rootNode) 3229 # Enable Python to collect the space used by the DOM. 3230 doc = None 3231 sys.stdout.write('from %(module_name)s import *\\n\\n') 3232 sys.stdout.write('rootObj = %(name)s(\\n') 3233 rootObj.exportLiteral(sys.stdout, 0, name_="%(name)s") 3234 sys.stdout.write(')\\n') 3235 return rootObj 3236 3237 class %(module_name)s: 3238 pass 3239 3240 3241 def main(): 3242 args = sys.argv[1:] 3243 if len(args) == 2 and args[0] == '-s': 3244 saxParse(args[1]) 3245 elif len(args) == 1: 3246 parse(args[0]) 3247 else: 3248 usage() 3249 3250 3251 if __name__ == '__main__': 3252 main() 3253 #import pdb 3254 #pdb.run('main()') 3255 3256 """ 3257 3258 3259 # Fool (and straighten out) the syntax highlighting. 3260 # DUMMY = ''' 3261 3262
3263 -def generateMain(outfile, prefix, root):
3264 name = root.getChildren()[0].getName() 3265 elType = cleanupName(root.getChildren()[0].getType()) 3266 if RootElement: 3267 rootElement = RootElement 3268 else: 3269 rootElement = elType 3270 params = { 3271 'prefix': prefix, 3272 'cap_name': cleanupName(make_gs_name(name)), 3273 'name': cleanupName(name), 3274 'module_name': os.path.splitext(os.path.basename(outfile.name))[0], 3275 'root': rootElement, 3276 } 3277 s1 = TEMPLATE_MAIN % params 3278 outfile.write(s1)
3279 3280
3281 -def buildCtorParams(element):
3282 content = [] 3283 add = content.append 3284 if element.isMixed(): 3285 add(', mixedclass_') 3286 add(', content_') 3287 else: 3288 buildCtorParams_aux(add, element) 3289 s1 = ''.join(content) 3290 return s1
3291 3292
3293 -def buildCtorParams_aux(add, element):
3294 base = element.getBase() 3295 if base and base in ElementDict: 3296 parent = ElementDict[base] 3297 buildCtorParams_aux(add, parent) 3298 attrDefs = element.getAttributeDefs() 3299 for key in attrDefs: 3300 attrDef = attrDefs[key] 3301 name = attrDef.getName() 3302 cleanName = cleanupName(mapName(name)) 3303 add(', %s' % cleanName) 3304 for child in element.getChildren(): 3305 add(', %s' % child.getCleanName())
3306 3307
3308 -def get_class_behavior_args(classBehavior):
3309 argList = [] 3310 args = classBehavior.getArgs() 3311 args = args.getArg() 3312 #print '(get_class_behavior_args) args:', args 3313 for arg in args: 3314 argList.append(arg.getName()) 3315 argString = ', '.join(argList) 3316 return argString
3317 3318 3319 # 3320 # Retrieve the implementation body via an HTTP request to a 3321 # URL formed from the concatenation of the baseImplUrl and the 3322 # implUrl. 3323 # An alternative implementation of get_impl_body() that also 3324 # looks in the local file system is commented out below. 3325 #
3326 -def get_impl_body(classBehavior, baseImplUrl, implUrl):
3327 impl = ' pass\n' 3328 if implUrl: 3329 if baseImplUrl: 3330 implUrl = '%s%s' % (baseImplUrl, implUrl) 3331 try: 3332 implFile = urllib2.urlopen(implUrl) 3333 impl = implFile.read() 3334 implFile.close() 3335 except urllib2.HTTPError: 3336 print '*** Implementation at %s not found.' % implUrl 3337 except urllib2.URLError: 3338 print '*** Connection refused for URL: %s' % implUrl 3339 return impl
3340 3341 ### 3342 ### This alternative implementation of get_impl_body() tries the URL 3343 ### via http first, then, if that fails, looks in a directory on 3344 ### the local file system (baseImplUrl) for a file (implUrl) 3345 ### containing the implementation body. 3346 ### 3347 ##def get_impl_body(classBehavior, baseImplUrl, implUrl): 3348 ## impl = ' pass\n' 3349 ## if implUrl: 3350 ## trylocal = 0 3351 ## if baseImplUrl: 3352 ## implUrl = '%s%s' % (baseImplUrl, implUrl) 3353 ## try: 3354 ## implFile = urllib2.urlopen(implUrl) 3355 ## impl = implFile.read() 3356 ## implFile.close() 3357 ## except Exception: 3358 ## trylocal = 1 3359 ## if trylocal: 3360 ## try: 3361 ## implFile = file(implUrl) 3362 ## impl = implFile.read() 3363 ## implFile.close() 3364 ## except Exception: 3365 ## print '*** Implementation at %s not found.' % implUrl 3366 ## return impl 3367 3368
3369 -def generateClassBehaviors(wrt, classBehaviors, baseImplUrl):
3370 for classBehavior in classBehaviors: 3371 behaviorName = classBehavior.getName() 3372 # 3373 # Generate the core behavior. 3374 argString = get_class_behavior_args(classBehavior) 3375 if argString: 3376 wrt(' def %s(self, %s, *args):\n' % (behaviorName, argString)) 3377 else: 3378 wrt(' def %s(self, *args):\n' % (behaviorName,)) 3379 implUrl = classBehavior.getImpl_url() 3380 impl = get_impl_body(classBehavior, baseImplUrl, implUrl) 3381 wrt(impl) 3382 wrt('\n') 3383 # 3384 # Generate the ancillaries for this behavior. 3385 ancillaries = classBehavior.getAncillaries() 3386 if ancillaries: 3387 ancillaries = ancillaries.getAncillary() 3388 if ancillaries: 3389 for ancillary in ancillaries: 3390 argString = get_class_behavior_args(ancillary) 3391 if argString: 3392 wrt(' def %s(self, %s, *args):\n' % (ancillary.getName(), argString)) 3393 else: 3394 wrt(' def %s(self, *args):\n' % (ancillary.getName(),)) 3395 implUrl = ancillary.getImpl_url() 3396 impl = get_impl_body(classBehavior, baseImplUrl, implUrl) 3397 wrt(impl) 3398 wrt('\n') 3399 # 3400 # Generate the wrapper method that calls the ancillaries and 3401 # the core behavior. 3402 argString = get_class_behavior_args(classBehavior) 3403 if argString: 3404 wrt(' def %s_wrapper(self, %s, *args):\n' % (behaviorName, argString)) 3405 else: 3406 wrt(' def %s_wrapper(self, *args):\n' % (behaviorName,)) 3407 if ancillaries: 3408 for ancillary in ancillaries: 3409 role = ancillary.getRole() 3410 if role == 'DBC-precondition': 3411 wrt(' if not self.%s(*args)\n' % (ancillary.getName(),)) 3412 wrt(' return False\n') 3413 if argString: 3414 wrt(' result = self.%s(%s, *args)\n' % (behaviorName, argString)) 3415 else: 3416 wrt(' result = self.%s(*args)\n' % (behaviorName,)) 3417 if ancillaries: 3418 for ancillary in ancillaries: 3419 role = ancillary.getRole() 3420 if role == 'DBC-postcondition': 3421 wrt(' if not self.%s(*args)\n' % (ancillary.getName(),)) 3422 wrt(' return False\n') 3423 wrt(' return result\n') 3424 wrt('\n')
3425 3426
3427 -def generateSubclass(outfile, element, prefix, xmlbehavior, behaviors, baseUrl):
3428 wrt = outfile.write 3429 if not element.isComplex(): 3430 return 3431 if (not element.getChildren()) and (not element.getAttributeDefs()): 3432 return 3433 if element.getName() in AlreadyGenerated_subclass: 3434 return 3435 AlreadyGenerated_subclass.append(element.getName()) 3436 name = element.getCleanName() 3437 wrt('class %s%s%s(supermod.%s):\n' % (prefix, name, SubclassSuffix, name)) 3438 s1 = buildCtorArgs_multilevel(element) 3439 wrt(' def __init__(self%s):\n' % s1) 3440 s1 = buildCtorParams(element) 3441 wrt(' supermod.%s%s.__init__(self%s)\n' % (prefix, name, s1)) 3442 if xmlbehavior and behaviors: 3443 wrt('\n') 3444 wrt(' #\n') 3445 wrt(' # XMLBehaviors\n') 3446 wrt(' #\n') 3447 # Get a list of behaviors for this class/subclass. 3448 classDictionary = behaviors.get_class_dictionary() 3449 if name in classDictionary: 3450 classBehaviors = classDictionary[name] 3451 else: 3452 classBehaviors = None 3453 if classBehaviors: 3454 generateClassBehaviors(wrt, classBehaviors, baseUrl) 3455 wrt('supermod.%s.subclass = %s%s\n' % (name, name, SubclassSuffix)) 3456 wrt('# end class %s%s%s\n' % (prefix, name, SubclassSuffix)) 3457 wrt('\n\n')
3458 3459 3460 TEMPLATE_SUBCLASS_HEADER = """\ 3461 #!/usr/bin/env python 3462 3463 # 3464 # Generated %s by EDGenerateDS.py. 3465 # 3466 3467 import sys 3468 from xml.dom import minidom 3469 from xml.sax import handler, make_parser 3470 3471 import %s as supermod 3472 3473 """ 3474 3475 TEMPLATE_SUBCLASS_FOOTER = """\ 3476 3477 # 3478 # SAX handler used to determine the top level element. 3479 # 3480 class SaxSelectorHandler(handler.ContentHandler): 3481 def __init__(self): 3482 self.topElementName = None 3483 def getTopElementName(self): 3484 return self.topElementName 3485 def startElement(self, name, attrs): 3486 self.topElementName = name 3487 raise StopIteration 3488 3489 3490 def parseSelect(inFileName): 3491 infile = file(inFileName, 'r') 3492 topElementName = None 3493 parser = make_parser() 3494 documentHandler = SaxSelectorHandler() 3495 parser.setContentHandler(documentHandler) 3496 try: 3497 try: 3498 parser.parse(infile) 3499 except StopIteration: 3500 topElementName = documentHandler.getTopElementName() 3501 if topElementName is None: 3502 raise RuntimeError, 'no top level element' 3503 topElementName = topElementName.replace('-', '_').replace(':', '_') 3504 if topElementName not in supermod.__dict__: 3505 raise RuntimeError, 'no class for top element: %%s' %% topElementName 3506 topElement = supermod.__dict__[topElementName] 3507 infile.seek(0) 3508 doc = minidom.parse(infile) 3509 finally: 3510 infile.close() 3511 rootNode = doc.childNodes[0] 3512 rootObj = topElement.factory() 3513 rootObj.build(rootNode) 3514 # Enable Python to collect the space used by the DOM. 3515 doc = None 3516 sys.stdout.write('<?xml version="1.0" ?>\\n') 3517 rootObj.export(sys.stdout, 0) 3518 return rootObj 3519 3520 3521 def saxParse(inFileName): 3522 parser = make_parser() 3523 documentHandler = supermod.Sax%(cap_name)sHandler() 3524 parser.setDocumentHandler(documentHandler) 3525 parser.parse('file:%%s' %% inFileName) 3526 rootObj = documentHandler.getRoot() 3527 #sys.stdout.write('<?xml version="1.0" ?>\\n') 3528 #rootObj.export(sys.stdout, 0) 3529 return rootObj 3530 3531 3532 def saxParseString(inString): 3533 parser = make_parser() 3534 documentHandler = supermod.SaxContentHandler() 3535 parser.setDocumentHandler(documentHandler) 3536 parser.feed(inString) 3537 parser.close() 3538 rootObj = documentHandler.getRoot() 3539 #sys.stdout.write('<?xml version="1.0" ?>\\n') 3540 #rootObj.export(sys.stdout, 0) 3541 return rootObj 3542 3543 3544 def parse(inFilename): 3545 doc = minidom.parse(inFilename) 3546 rootNode = doc.documentElement 3547 rootObj = supermod.%(root)s.factory() 3548 rootObj.build(rootNode) 3549 # Enable Python to collect the space used by the DOM. 3550 doc = None 3551 sys.stdout.write('<?xml version="1.0" ?>\\n') 3552 rootObj.export(sys.stdout, 0, name_="%(name)s") 3553 doc = None 3554 return rootObj 3555 3556 3557 def parseString(inString): 3558 doc = minidom.parseString(inString) 3559 rootNode = doc.documentElement 3560 rootObj = supermod.%(root)s.factory() 3561 rootObj.build(rootNode) 3562 # Enable Python to collect the space used by the DOM. 3563 doc = None 3564 sys.stdout.write('<?xml version="1.0" ?>\\n') 3565 rootObj.export(sys.stdout, 0, name_="%(name)s") 3566 return rootObj 3567 3568 3569 def parseLiteral(inFilename): 3570 doc = minidom.parse(inFilename) 3571 rootNode = doc.documentElement 3572 rootObj = supermod.%(root)s.factory() 3573 rootObj.build(rootNode) 3574 # Enable Python to collect the space used by the DOM. 3575 doc = None 3576 sys.stdout.write('from %(super)s import *\\n\\n') 3577 sys.stdout.write('rootObj = %(name)s(\\n') 3578 rootObj.exportLiteral(sys.stdout, 0, name_="%(name)s") 3579 sys.stdout.write(')\\n') 3580 return rootObj 3581 3582 3583 USAGE_TEXT = \"\"\" 3584 Usage: python ???.py <infilename> 3585 \"\"\" 3586 3587 def usage(): 3588 print USAGE_TEXT 3589 sys.exit(-1) 3590 3591 3592 def main(): 3593 args = sys.argv[1:] 3594 if len(args) != 1: 3595 usage() 3596 infilename = args[0] 3597 root = parse(infilename) 3598 3599 3600 if __name__ == '__main__': 3601 main() 3602 #import pdb 3603 #pdb.run('main()') 3604 3605 3606 """ 3607 3608 ##def isMember(item, lst): 3609 ## for item1 in lst: 3610 ## if item == item1: 3611 ## print '(isMember) found name: %s' % item 3612 ## return True 3613 ## print '(isMember) did not find name: %s' % item 3614 ## return False 3615 3616
3617 -def generateSubclasses(root, subclassFilename, behaviorFilename, 3618 prefix, superModule='xxx'):
3619 name = root.getChildren()[0].getName() 3620 subclassFile = makeFile(subclassFilename) 3621 if subclassFile: 3622 # Read in the XMLBehavior file. 3623 xmlbehavior = None 3624 behaviors = None 3625 baseUrl = None 3626 if behaviorFilename: 3627 try: 3628 # Add the currect working directory to the path so that 3629 # we use the user/developers local copy. 3630 sys.path.insert(0, '.') 3631 import xmlbehavior_sub as xmlbehavior 3632 except ImportError: 3633 print '*** You have requested generation of extended methods.' 3634 print '*** But, no xmlbehavior module is available.' 3635 print '*** Generation of extended behavior methods is omitted.' 3636 if xmlbehavior: 3637 behaviors = xmlbehavior.parse(behaviorFilename) 3638 behaviors.make_class_dictionary(cleanupName) 3639 baseUrl = behaviors.getBase_impl_url() 3640 wrt = subclassFile.write 3641 wrt(TEMPLATE_SUBCLASS_HEADER % (time.ctime(), superModule)) 3642 for element in ElementsForSubclasses: 3643 generateSubclass(subclassFile, element, prefix, xmlbehavior, behaviors, baseUrl) 3644 ## processed = [] 3645 ## for element in root.getChildren(): 3646 ## name = element.getCleanName() 3647 ## if name not in processed: 3648 ## processed.append(name) 3649 ## generateSubclass(subclassFile, element, prefix, xmlbehavior, behaviors, baseUrl) 3650 ## while 1: 3651 ## if len(DelayedElements_subclass) <= 0: 3652 ## break 3653 ## element = DelayedElements_subclass.pop() 3654 ## name = element.getCleanName() 3655 ## if name not in processed: 3656 ## processed.append(name) 3657 ## generateSubclass(subclassFile, element, prefix, xmlbehavior, behaviors, baseUrl) 3658 name = root.getChildren()[0].getName() 3659 elType = cleanupName(root.getChildren()[0].getType()) 3660 if RootElement: 3661 rootElement = RootElement 3662 else: 3663 rootElement = elType 3664 params = { 3665 'cap_name': make_gs_name(cleanupName(name)), 3666 'name': cleanupName(name), 3667 'module_name': os.path.splitext(os.path.basename(subclassFilename))[0], 3668 'root': rootElement, 3669 'super': superModule, 3670 } 3671 wrt(TEMPLATE_SUBCLASS_FOOTER % params) 3672 subclassFile.close()
3673 3674
3675 -def generateFromTree(outfile, prefix, elements, processed):
3676 for element in elements: 3677 name = element.getCleanName() 3678 if 1: # if name not in processed: 3679 processed.append(name) 3680 generateClasses(outfile, prefix, element, 0) 3681 children = element.getChildren() 3682 if children: 3683 generateFromTree(outfile, prefix, element.getChildren(), processed)
3684 3685
3686 -def generate(outfileName, subclassFilename, behaviorFilename, 3687 prefix, root, superModule):
3688 global DelayedElements, DelayedElements_subclass 3689 # Create an output file. 3690 # Note that even if the user does not request an output file, 3691 # we still need to go through the process of generating classes 3692 # because it produces data structures needed during generation of 3693 # subclasses. 3694 outfile = None 3695 if outfileName: 3696 outfile = makeFile(outfileName) 3697 if not outfile: 3698 outfile = os.tmpfile() 3699 processed = [] 3700 generateHeader(outfile, prefix) 3701 DelayedElements = [] 3702 DelayedElements_subclass = [] 3703 elements = root.getChildren() 3704 generateFromTree(outfile, prefix, elements, processed) 3705 while 1: 3706 if len(DelayedElements) <= 0: 3707 break 3708 element = DelayedElements.pop() 3709 name = element.getCleanName() 3710 if name not in processed: 3711 processed.append(name) 3712 generateClasses(outfile, prefix, element, 1) 3713 # 3714 # Generate the elements that were postponed because we had not 3715 # yet generated their base class. 3716 while 1: 3717 if len(PostponedExtensions) <= 0: 3718 break 3719 element = PostponedExtensions.pop() 3720 base = element.getBase() 3721 if base and base in ElementDict: 3722 parent = ElementDict[base] 3723 parentName = parent.getName() 3724 if (parentName in AlreadyGenerated or 3725 parentName in SimpleTypeDict.keys()): 3726 generateClasses(outfile, prefix, element, 1) 3727 else: 3728 PostponedExtensions.insert(0, element) 3729 # 3730 # Disable the generation of SAX handler/parser. 3731 # It failed when we stopped putting simple types into ElementDict. 3732 # When there are duplicate names, the SAX parser probably does 3733 # not work anyway. 3734 generateSAXHndlr(outfile, root) 3735 generateMain(outfile, prefix, root) 3736 outfile.close() 3737 if subclassFilename: 3738 generateSubclasses(root, subclassFilename, behaviorFilename, 3739 prefix, superModule)
3740 3741
3742 -def makeFile(outFileName):
3743 global Force 3744 outFile = None 3745 if (not Force) and os.path.exists(outFileName): 3746 reply = raw_input('File %s exists. Overwrite? (y/n): ' % outFileName) 3747 if reply == 'y': 3748 outFile = file(outFileName, 'w') 3749 else: 3750 outFile = file(outFileName, 'w') 3751 return outFile
3752 3753
3754 -def mapName(oldName):
3755 global NameTable 3756 newName = oldName 3757 if NameTable: 3758 if oldName in NameTable: 3759 newName = NameTable[oldName] 3760 return newName
3761
3762 -def cleanupName(oldName):
3763 newName = oldName.replace(':', '_') 3764 newName = newName.replace('-', '_') 3765 newName = newName.replace('.', '_') 3766 return newName
3767
3768 -def make_gs_name(oldName):
3769 if UseOldGetterSetter: 3770 #newName = oldName.capitalize() 3771 newName = oldName[0].capitalize() 3772 if len(oldName) > 1: 3773 newName += oldName[1:] 3774 else: 3775 newName = '_%s' % oldName 3776 return newName
3777 3778 ## def mapName(oldName): 3779 ## return '_X_%s' % oldName 3780 3781
3782 -def strip_namespace(val):
3783 return val.split(':')[-1]
3784 3785
3786 -def parseAndGenerate(outfileName, subclassFilename, prefix, \ 3787 xschemaFileName, behaviorFilename, superModule='???'):
3788 global DelayedElements, DelayedElements_subclass, AlreadyGenerated, SaxDelayedElements, \ 3789 AlreadyGenerated_subclass, UserMethodsPath, UserMethodsModule 3790 DelayedElements = [] 3791 DelayedElements_subclass = [] 3792 AlreadyGenerated = [] 3793 AlreadyGenerated_subclass = [] 3794 if UserMethodsPath: 3795 UserMethodsModule = __import__(UserMethodsPath) 3796 ## parser = saxexts.make_parser("xml.sax.drivers2.drv_pyexpat") 3797 parser = make_parser() 3798 ## print 'dir(parser):', dir(parser) 3799 ## print "Parser: %s" % parser 3800 dh = XschemaHandler() 3801 ## parser.setDocumentHandler(dh) 3802 parser.setContentHandler(dh) 3803 if xschemaFileName == '-': 3804 parser.parse(sys.stdin) 3805 else: 3806 parser.parse(xschemaFileName) 3807 root = dh.getRoot() 3808 root.annotate() 3809 ## print 'ElementDict:', ElementDict 3810 ## for name, obj in ElementDict.iteritems(): 3811 ## print ' ', name, obj.getName(), obj.type 3812 ## print '=' * 50 3813 ## root.show(sys.stdout, 0) 3814 ## print '=' * 50 3815 ## response = raw_input('Press Enter') 3816 ## root.show(sys.stdout, 0) 3817 ## print '=' * 50 3818 ## print ']]] root: ', root, '[[[' 3819 generate(outfileName, subclassFilename, behaviorFilename, 3820 prefix, root, superModule)
3821 3822 3823 3824 USAGE_TEXT = __doc__ 3825
3826 -def usage():
3827 print USAGE_TEXT 3828 sys.exit(-1)
3829 3830
3831 -def main():
3832 global Force, GenerateProperties, SubclassSuffix, RootElement, \ 3833 ValidatorBodiesBasePath, UseOldGetterSetter, \ 3834 UserMethodsPath, XsdNameSpace 3835 args = sys.argv[1:] 3836 options, args = getopt.getopt(args, 'hfyo:s:p:a:b:mu:', 3837 ['help', 'subclass-suffix=', 'root-element=', 'super=', 3838 'validator-bodies=', 'use-old-getter-setter', 3839 'user-methods=', 3840 ]) 3841 prefix = '' 3842 outFilename = None 3843 subclassFilename = None 3844 behaviorFilename = None 3845 nameSpace = 'xs:' 3846 superModule = '???' 3847 for option in options: 3848 if option[0] == '-h' or option[0] == '--help': 3849 usage() 3850 elif option[0] == '-p': 3851 prefix = option[1] 3852 elif option[0] == '-o': 3853 outFilename = option[1] 3854 elif option[0] == '-s': 3855 subclassFilename = option[1] 3856 elif option[0] == '-f': 3857 Force = 1 3858 elif option[0] == '-a': 3859 nameSpace = option[1] 3860 elif option[0] == '-b': 3861 behaviorFilename = option[1] 3862 elif option[0] == '-m': 3863 GenerateProperties = 1 3864 elif option[0] == '--subclass-suffix': 3865 SubclassSuffix = option[1] 3866 elif option[0] == '--root-element': 3867 RootElement = option[1] 3868 elif option[0] == '--super': 3869 superModule = option[1] 3870 elif option[0] == '--validator-bodies': 3871 ValidatorBodiesBasePath = option[1] 3872 elif option[0] == '--use-old-getter-setter': 3873 UseOldGetterSetter = 1 3874 elif option[0] in ('-u', '--user-methods'): 3875 UserMethodsPath = option[1] 3876 XsdNameSpace = nameSpace 3877 set_type_constants(nameSpace) 3878 if behaviorFilename and not subclassFilename: 3879 print '\n*** Error. -b requires -s' 3880 usage() 3881 if len(args) != 1: 3882 usage() 3883 xschemaFileName = args[0] 3884 parseAndGenerate(outFilename, subclassFilename, prefix, \ 3885 xschemaFileName, behaviorFilename, superModule=superModule)
3886 3887 3888 if __name__ == '__main__': 3889 main() 3890 ## import pdb 3891 ## pdb.run('main()') 3892