1#!/usr/bin/python 2############################################################################# 3# Software Testing Automation Framework (STAF) # 4# (C) Copyright IBM Corp. 2001, 2005 # 5# # 6# This software is licensed under the Eclipse Public License (EPL) V1.0. # 7############################################################################# 8 9import PYSTAF 10 11# Utility functions 12 13def STAFWrapData(message): 14 return ":%d:%s" % (len(message), message) 15 16# Allows you to access this function using either name 17wrapData = STAFWrapData 18 19# Privacy utility methods 20 21def STAFAddPrivacyDelimiters(data): 22 return "%s" % (PYSTAF.STAFAddPrivacyDelimiters(data)) 23 24def STAFEscapePrivacyDelimiters(data): 25 return "%s" % (PYSTAF.STAFEscapePrivacyDelimiters(data)) 26 27def STAFMaskPrivateData(data): 28 return "%s" % (PYSTAF.STAFMaskPrivateData(data)) 29 30def STAFRemovePrivacyDelimiters(data, numLevels = 0): 31 return "%s" % (PYSTAF.STAFRemovePrivacyDelimiters(data, numLevels)) 32 33# Allows you to access these functions using either name 34addPrivacyDelimiters = STAFAddPrivacyDelimiters 35escapePrivacyDelimiters = STAFEscapePrivacyDelimiters 36maskPrivateData = STAFMaskPrivateData 37removePrivacyDelimiters = STAFRemovePrivacyDelimiters 38 39# STAFException class 40 41class STAFException: 42 43 def __init__(self, rc = 0, result = ""): 44 self.rc = rc 45 self.result = result 46 47# STAFResult class 48 49class STAFResult: 50 51 Ok = 0 52 InvalidAPI = 1 53 UnknownService = 2 54 InvalidHandle = 3 55 HandleAlreadyExists = 4 56 HandleDoesNotExist = 5 57 UnknownError = 6 58 InvalidRequestString = 7 59 InvalidServiceResult = 8 60 REXXError = 9 61 BaseOSError = 10 62 ProcessAlreadyComplete = 11 63 ProcessNotComplete = 12 64 VariableDoesNotExist = 13 65 UnResolvableString = 14 66 InvalidResolveString = 15 67 NoPathToMachine = 16 68 FileOpenError = 17 69 FileReadError = 18 70 FileWriteError = 19 71 FileDeleteError = 20 72 STAFNotRunning = 21 73 CommunicationError = 22 74 TrusteeDoesNotExist = 23 75 InvalidTrustLevel = 24 76 AccessDenied = 25 77 STAFRegistrationError = 26 78 ServiceConfigurationError = 27 79 QueueFull = 28 80 NoQueueElement = 29 81 NotifieeDoesNotExist = 30 82 InvalidAPILevel = 31 83 ServiceNotUnregisterable = 32 84 ServiceNotAvailable = 33 85 SemaphoreDoesNotExist = 34 86 NotSemaphoreOwner = 35 87 SemaphoreHasPendingRequests = 36 88 Timeout = 37 89 JavaError = 38 90 ConverterError = 39 91 MoveError = 40 92 InvalidObject = 41 93 InvalidParm = 42 94 RequestNumberNotFound = 43 95 InvalidAsynchOption = 44 96 RequestNotComplete = 45 97 ProcessAuthenticationDenied = 46 98 InvalidValue = 47 99 DoesNotExist = 48 100 AlreadyExists = 49 101 DirectoryNotEmpty = 50 102 DirectoryCopyError = 51 103 DiagnosticsNotEnabled = 52 104 HandleAuthenticationDenied = 53 105 HandleAlreadyAuthenticated = 54 106 InvalidSTAFVersion = 55 107 RequestCancelled = 56 108 CreateThreadError = 57 109 MaximumSizeExceeded = 58 110 MaximumHandlesExceeded = 59 111 NotRequester = 60 112 113 def __init__(self, rc = 0, result = ""): 114 self.rc = rc 115 self.result = result 116 self.resultContext = None 117 self.resultObj = None 118 119 def __init__(self, rc, result, doUnmarshallResult): 120 self.rc = rc 121 self.result = result 122 if doUnmarshallResult: 123 self.resultContext = unmarshall(self.result) 124 self.resultObj = self.resultContext.getRootObject() 125 else: 126 self.resultContext = None 127 self.resultObj = None 128 129# STAFHandle class 130 131class STAFHandle: 132 133 # STAFHandle types 134 135 Standard = 0 136 Static = 1 137 138 # Modes for submit call 139 140 Synchronous = 0 141 FireAndForget = 1 142 Queue = 2 143 Retain = 3 144 QueueRetain = 4 145 146 # Note: I would have liked to have used STAFHandle.Standard in place of "0" 147 # in the methods below, but the class hasn't been defined yet. 148 149 def __init__(self, handleNameOrNumber, handleType = 0): 150 151 self.handleType = handleType 152 self.doUnmarshallResult = 1 153 154 if (handleType == STAFHandle.Standard): 155 if (type(handleNameOrNumber) != types.StringType): 156 raise TypeError, 'A string is required if using standard handle type' 157 rc, self.handle = PYSTAF.STAFRegister(handleNameOrNumber) 158 if (rc != 0): 159 raise STAFException(rc) 160 else: 161 if (type(handleNameOrNumber) != types.IntType): 162 raise TypeError, 'An integer is required if using static handle type' 163 self.handle = handleNameOrNumber 164 165 def submit(self, location, service, request, mode = Synchronous): 166 rc, result = PYSTAF.STAFSubmit(self.handle, mode, location, service, request) 167 return STAFResult(rc, result, self.doUnmarshallResult) 168 169 def unregister(self): 170 if (self.handleType == 0): 171 rc = PYSTAF.STAFUnregister(self.handle) 172 if (rc != 0): 173 raise STAFException(rc) 174 self.handle = 0 175 176 return 0 177 178 # Set a flag (0, 1) to indicate if the result should be auto-unmarshalled 179 def setDoUnmarshallResult(self, flag): 180 if flag: 181 self.doUnmarshallResult = 1 182 else: 183 self.doUnmarshallResult = 0 184 185 # Retrieve the auto-unmarshall result flag 186 def getDoUnmarshallResult(self): 187 return self.doUnmarshallResult 188 189 190# Marshalling constants and imports 191 192import types 193 194UNMARSHALLING_DEFAULTS = 0 195IGNORE_INDIRECT_OBJECTS = 1 196 197MARSHALLED_DATA_MARKER = '@SDT/' 198NONE_MARKER = '@SDT/$0:0:' 199SCALAR_MARKER = '@SDT/$' 200SCALAR_STRING_MARKER = '@SDT/$S' 201LIST_MARKER = '@SDT/[' 202MAP_MARKER = '@SDT/{' 203MC_INSTANCE_MARKER = '@SDT/%' 204CONTEXT_MARKER = '@SDT/*' 205 206# Formatting constants and imports 207 208import os 209 210NONE_STRING = '<None>' 211DISPLAY_NAME_KEY = 'display-name' 212MAP_CLASS_MAP_KEY = 'map-class-map' 213MAP_CLASS_NAME_KEY = 'staf-map-class-name' 214ENTRY_SEPARATOR = '' 215INDENT_DELTA = 2 216# 80 spaces 217SPACES = (' ' + 218 ' ') 219 220# STAFMapClassDefinitionClass 221 222class STAFMapClassDefinition: 223 # Constructors 224 def __init__(self, name = None, mapClassDef = None): 225 if (mapClassDef is None) and (name is None): 226 self.mapClassDef = { 'name': '', 'keys': [] } 227 elif (name is not None): 228 self.mapClassDef = { 'name': name, 'keys': [] } 229 else: 230 self.mapClassDef = mapClassDef 231 232 def createInstance(self): 233 return { 'staf-map-class-name' : self.mapClassDef['name'] } 234 235 def addKey(self, keyName, displayName = None): 236 theKey = { 'key': keyName } 237 if displayName is not None: 238 theKey['display-name'] = displayName 239 self.mapClassDef['keys'].append(theKey) 240 241 def setKeyProperty(self, keyName, property, value): 242 for key in self.mapClassDef['keys']: 243 if key['key'] == keyName: 244 key[property] = value 245 246 def keys(self): 247 return self.mapClassDef['keys'] 248 249 def name(self): 250 return self.mapClassDef['name'] 251 252 def getMapClassDefinitionObject(self): 253 return self.mapClassDef 254 255 def __str__(self): 256 return formatObject(self.mapClassDef) 257 258 def __repr__(self): 259 return formatObject(self.mapClassDef) 260 261# STAFMarshallingContext class 262 263class STAFMarshallingContext: 264 265 def isMarshalledData(self, someData): 266 return someData.startswith('@SDT/') 267 268 def __init__(self, obj = None, mapClassMap = None): 269 if mapClassMap is None: 270 self.mapClassMap = {} 271 else: 272 self.mapClassMap = mapClassMap 273 self.rootObject = obj 274 275 def setMapClassDefinition(self, mapClassDef): 276 self.mapClassMap[mapClassDef.name()] = mapClassDef.getMapClassDefinitionObject() 277 278 def getMapClassDefinition(self, mapClassName): 279 return STAFMapClassDefinition( 280 mapClassDef = self.mapClassMap.get(mapClassName, None)) 281 282 def hasMapClassDefinition(self, mapClassName): 283 return self.mapClassMap.has_key(mapClassName) 284 285 def getMapClassMap(self): 286 return self.mapClassMap 287 288 def mapClassDefinitionIterator(self): 289 return self.mapClassMap.keys() 290 291 def setRootObject(self, rootObject): 292 self.rootObject = rootObject 293 294 def getRootObject(self): 295 return self.rootObject 296 297 def getPrimaryObject(self): 298 if len(self.mapClassMap.keys()) == 0: 299 return self.rootObject 300 else: 301 return self 302 303 def marshall(self): 304 return marshall(self, self) 305 306 def __str__(self): 307 return formatObject(self.rootObject, self) 308 309 # XXX: Change to show the key map class in addition? 310 def __repr__(self): 311 return formatObject(self.rootObject, self) 312 313# Function that tests if a string is marshalled data 314 315def isMarshalledData(someData): 316 return someData.startswith('@SDT/') 317 318# General marshalling function 319 320def marshall(object, context = None): 321 if object is None: 322 return NONE_MARKER 323 324 if type(object) == types.ListType: 325 326 # Build a list of strings and join them for performance reasons 327 328 listDataList = [] 329 330 for item in object: 331 listDataList.append(marshall(item, context)) 332 333 listData = ''.join(listDataList) 334 335 return "%s%s:%s:%s" % (LIST_MARKER, len(object), len(listData), listData) 336 337 if type(object) == types.DictType: 338 339 # If a staf-map-class-name key exists in the map, make sure that 340 # it's map class definition is provided in the marshalling context. 341 # If it's not, then treat the map as a plain map object. 342 343 isMapClass = 0 344 mapClassName = '' 345 346 if ((context is not None) and 347 (isinstance(context, STAFMarshallingContext)) and 348 (object.has_key('staf-map-class-name'))): 349 350 mapClassName = object['staf-map-class-name'] 351 352 if context.hasMapClassDefinition(mapClassName): 353 isMapClass = 1 354 355 if isMapClass: 356 357 mapClass = context.getMapClassDefinition(mapClassName) 358 359 # Build a list of strings and join them for performance reasons 360 361 mapDataList = [] 362 mapDataList.append(":%s:%s" % (len(mapClassName), mapClassName)) 363 364 for key in mapClass.keys(): 365 366 if object.has_key(key['key']): 367 thisObj = object[key['key']] 368 else: 369 thisObj = None 370 371 mapDataList.append(marshall(thisObj, context)) 372 373 mapData = ''.join(mapDataList) 374 375 return "%s:%s:%s" % (MC_INSTANCE_MARKER, len(mapData), mapData) 376 377 else: 378 379 # Build a list of strings and join them for performance reasons 380 381 mapDataList = [] 382 383 for key in object.keys(): 384 mapDataList.append( 385 ":%s:%s%s" % (len(str(key)), str(key), 386 marshall(object[key], context))) 387 388 mapData = ''.join(mapDataList) 389 390 return "%s:%s:%s" % (MAP_MARKER, len(mapData), mapData) 391 392 if isinstance(object, STAFMarshallingContext): 393 394 if len(object.mapClassMap.keys()) == 0: 395 return marshall(object.getRootObject(), context) 396 else: 397 contextMap = { 'map-class-map': object.mapClassMap } 398 399 # Note: We can't simply put the root object as a map key like 400 # "root-object" and then marshall the whole map, as in 401 # the unmarshalling routines, we need to be able to 402 # unmarshall the root object in the context of the 403 # map-class-map. 404 405 mcData = (marshall(contextMap, context) + 406 marshall(object.getRootObject(), object)) 407 408 return "%s:%s:%s" % (CONTEXT_MARKER, len(mcData), mcData) 409 410 # if object has method 'marshall': 411 412 return "%s:%s:%s" % (SCALAR_STRING_MARKER, len(str(object)), str(object)) 413 414# General unmarshalling function (catches all exceptions) 415# Unmarshalls the input data string and returns a marshalling context. 416# If an exception occurs, it returns a marshalling context of the 417# input data string 418 419def unmarshall(data, context = None, flags = UNMARSHALLING_DEFAULTS): 420 421 try: 422 423 if context is None: 424 context = STAFMarshallingContext() 425 426 if data.startswith(NONE_MARKER): 427 return STAFMarshallingContext() 428 429 elif data.startswith(SCALAR_MARKER): 430 431 # @SDT/$S:<string-length>:<String> 432 433 colonIndex = data.find(':', len(SCALAR_MARKER)) 434 435 if colonIndex == -1: 436 return STAFMarshallingContext(data) 437 438 dataIndex = colonIndex + 1 439 440 colonIndex = data.find(':', dataIndex) 441 442 if colonIndex == -1: 443 return STAFMarshallingContext(data) 444 445 stringLength = int(data[dataIndex:colonIndex]) 446 447 dataIndex = colonIndex + 1 448 449 if stringLength != (len(data) - dataIndex): 450 return STAFMarshallingContext(data) 451 452 theString = data[dataIndex:] 453 454 if (theString.startswith(MARSHALLED_DATA_MARKER) and 455 ((flags & IGNORE_INDIRECT_OBJECTS) != 456 IGNORE_INDIRECT_OBJECTS)): 457 return unmarshall(theString, context, flags) 458 else: 459 return STAFMarshallingContext(theString) 460 461 elif data.startswith(LIST_MARKER): 462 463 # @SDT/[<number-of-items>:<array-length>:<SDT-Any-1>...<SDT-Any-n> 464 465 # Get number-of-items in the list 466 467 colonIndex = data.find(':', len(LIST_MARKER)) 468 469 if colonIndex == -1: 470 return STAFMarshallingContext(data) 471 472 numItems = int(data[len(LIST_MARKER):colonIndex]) 473 474 # Get array-length 475 476 dataIndex = colonIndex + 1 477 478 colonIndex = data.find(':', dataIndex) 479 480 if colonIndex == -1: 481 return STAFMarshallingContext(data) 482 483 arrayLength = int(data[dataIndex:colonIndex]) 484 485 dataIndex = colonIndex + 1 486 487 if arrayLength != (len(data) - dataIndex): 488 return STAFMarshallingContext(data) 489 490 # Create a list of the data 491 492 list = [] 493 494 for i in range(numItems): 495 496 # Get the next item in the list and unmarshall it and add it 497 # to the list 498 499 colonIndex1 = data.find(':', dataIndex) 500 501 if colonIndex1 == -1: 502 return STAFMarshallingContext(data) 503 504 colonIndex2 = data.find(':', colonIndex1 + 1) 505 506 if colonIndex2 == -1: 507 return STAFMarshallingContext(data) 508 509 itemLength = int(data[colonIndex1 + 1:colonIndex2]) 510 511 list.append( 512 unmarshall(data[dataIndex:colonIndex2 + itemLength + 1], 513 context, flags).getPrimaryObject()) 514 515 dataIndex = colonIndex2 + itemLength + 1 516 517 return STAFMarshallingContext(list) 518 519 elif data.startswith(MAP_MARKER): 520 521 # @SDT/{:<map-length>::<key-1-length>:<key-1><SDT-Any> 522 # ... 523 # :<key-n-length>:<key-1><SDT-Any> 524 525 # Get map-length 526 527 colonIndex = data.find(':', len(MAP_MARKER)) 528 529 if colonIndex == -1: 530 return STAFMarshallingContext(data) 531 532 dataIndex = colonIndex + 1 533 534 colonIndex = data.find(':', dataIndex) 535 536 if colonIndex == -1: 537 return STAFMarshallingContext(data) 538 539 mapLength = int(data[dataIndex:colonIndex]) 540 541 dataIndex = colonIndex + 1 542 543 if mapLength != (len(data) - dataIndex): 544 return STAFMarshallingContext(data) 545 546 # Create the map (aka dictionary) of data 547 548 map = {} 549 550 while dataIndex < len(data): 551 552 # Get the key first 553 554 keyColonIndex1 = data.find(':', dataIndex) 555 556 if keyColonIndex1 == -1: 557 return STAFMarshallingContext(data) 558 559 keyColonIndex2 = data.find(':', keyColonIndex1 + 1) 560 561 if keyColonIndex2 == -1: 562 return STAFMarshallingContext(data) 563 564 keyLength = int(data[keyColonIndex1 + 1:keyColonIndex2]) 565 key = data[keyColonIndex2 + 1:keyColonIndex2 + 1 + keyLength] 566 567 dataIndex = keyColonIndex2 + 1 + keyLength 568 569 # Now, get the object 570 571 colonIndex1 = data.find(':', dataIndex) 572 573 if colonIndex1 == -1: 574 return STAFMarshallingContext(data) 575 576 colonIndex2 = data.find(':', colonIndex1 + 1) 577 578 if colonIndex2 == -1: 579 return STAFMarshallingContext(data) 580 581 itemLength = int(data[colonIndex1 + 1:colonIndex2]) 582 583 map[key] = unmarshall( 584 data[dataIndex:colonIndex2 + itemLength + 1], 585 context, flags).getPrimaryObject() 586 587 dataIndex = colonIndex2 + itemLength + 1 588 589 return STAFMarshallingContext(map) 590 591 elif data.startswith(MC_INSTANCE_MARKER): 592 593 # @SDT/%:<map-class-instance-length>::<map-class-name-length>: 594 # <map-class-name><SDT-Any-value-1>...<SDT-Any-value-n> 595 596 # Get the map-class-instance-length 597 598 colonIndex = data.find(':', len(MC_INSTANCE_MARKER)) 599 600 if colonIndex == -1: 601 return STAFMarshallingContext(data) 602 603 dataIndex = colonIndex + 1 604 605 colonIndex = data.find(':', dataIndex) 606 607 if colonIndex == -1: 608 return STAFMarshallingContext(data) 609 610 mapClassInstanceLength = int(data[dataIndex:colonIndex]) 611 612 dataIndex = colonIndex + 1 613 614 if mapClassInstanceLength != (len(data) - dataIndex): 615 return STAFMarshallingContext(data) 616 617 # Get map-class-name-length 618 619 colonIndex = data.find(':', dataIndex) 620 621 if colonIndex == -1: 622 return STAFMarshallingContext(data) 623 624 dataIndex = colonIndex + 1 625 626 colonIndex = data.find(':', dataIndex) 627 628 if colonIndex == -1: 629 return STAFMarshallingContext(data) 630 631 mapClassNameLength = int(data[dataIndex:colonIndex]) 632 633 # Get map-class-name 634 635 dataIndex = colonIndex + 1 636 637 mapClassName = data[dataIndex : dataIndex + mapClassNameLength] 638 639 dataIndex = dataIndex + mapClassNameLength 640 641 # Create a map and add the the staf-map-class-name key and value 642 # to the map 643 644 map = { 'staf-map-class-name': mapClassName } 645 646 # Unmarshall all of the actual keys and add to the map 647 648 mapClass = context.getMapClassDefinition(mapClassName) 649 keys = mapClass.keys() 650 keyIndex = 0 651 652 while dataIndex < len(data): 653 colonIndex = data.find(':', dataIndex) 654 655 if colonIndex == -1: 656 return STAFMarshallingContext(data) 657 658 colonIndex2 = data.find(':', colonIndex + 1) 659 660 if colonIndex2 == -1: 661 return STAFMarshallingContext(data) 662 663 itemLength = int(data[colonIndex + 1:colonIndex2]) 664 665 map[keys[keyIndex]['key']] = unmarshall( 666 data[dataIndex:colonIndex2 + itemLength + 1], 667 context, flags).getPrimaryObject() 668 669 dataIndex = colonIndex2 + itemLength + 1 670 keyIndex = keyIndex + 1 671 672 return STAFMarshallingContext(map) 673 674 elif data.startswith(CONTEXT_MARKER): 675 676 # @SDT/*:<context-length>: 677 # @SDT/{:<mapClassLength>:<mapClassData><rootObject> 678 679 # Get context-length 680 681 colonIndex = data.find(':', len(CONTEXT_MARKER)) 682 683 if colonIndex == -1: 684 return STAFMarshallingContext(data) 685 686 contextIndex = data.find(':', colonIndex + 1) 687 688 if contextIndex == -1: 689 return STAFMarshallingContext(data) 690 691 contextLength = int(data[colonIndex + 1:contextIndex]) 692 693 contextIndex = contextIndex + 1 694 695 if contextLength != (len(data) - contextIndex): 696 return STAFMarshallingContext(data) 697 698 # Get mapClassLength 699 700 colonIndex = data.find(':', contextIndex) 701 702 if colonIndex == -1: 703 return STAFMarshallingContext(data) 704 705 mapIndex = contextIndex 706 mapDataIndex = data.find(':', colonIndex + 1) 707 708 if mapDataIndex == -1: 709 return STAFMarshallingContext(data) 710 711 mapLength = int(data[colonIndex + 1:mapDataIndex]) 712 713 mapDataIndex = mapDataIndex + 1 714 715 if mapLength > (len(data) - mapDataIndex): 716 return STAFMarshallingContext(data) 717 718 # Create a new marshalling context with the map classes 719 # and root object 720 721 contextMap = unmarshall(data[mapIndex:mapDataIndex + mapLength], 722 context, flags).getPrimaryObject() 723 mapClassMap = contextMap['map-class-map'] 724 newContext = STAFMarshallingContext(None, mapClassMap) 725 726 colonIndex = data.find(':', mapDataIndex + mapLength) 727 728 if colonIndex == -1: 729 return STAFMarshallingContext(data) 730 731 rootObjIndex = mapDataIndex + mapLength 732 rootObjDataIndex = data.find(':', colonIndex + 1) 733 734 if rootObjDataIndex == -1: 735 return STAFMarshallingContext(data) 736 737 rootObjLength = int(data[colonIndex + 1:rootObjDataIndex]) 738 739 rootObjDataIndex = rootObjDataIndex + 1 740 741 if rootObjLength > (len(data) - rootObjDataIndex): 742 return STAFMarshallingContext(data) 743 744 newContext.setRootObject( 745 unmarshall(data[rootObjIndex:rootObjDataIndex + rootObjLength], 746 newContext, flags).getPrimaryObject()) 747 748 return newContext 749 750 elif data.startswith(MARSHALLED_DATA_MARKER): 751 752 # Here, we don't know what the type is 753 return STAFMarshallingContext(data) 754 755 except: 756 # If any exception occurs unmarshalling the result, assume invalid 757 # marshalled data and return a new marshalling context of the input 758 # data string 759 return STAFMarshallingContext(data) 760 761 return STAFMarshallingContext(data) 762 763 764# Formatting function 765# 766# Notes: 767# 1) The indentLevel option is not meant to be used by a user calling 768# the formatObject procedure, thus we don't document it exernally. 769# It's meant to be used internally by the formatObject method when 770# recursively calling itself. 771# 2) The flags option is not currently used (it's for future use) 772 773def formatObject(obj, context = None, indentLevel = 0, flags = 0): 774 775 # Build a list of strings to output and join them for performance reasons 776 output = [] 777 778 if type(obj) == types.ListType: 779 list = obj 780 output.append('[') 781 indentLevel = indentLevel + 1 782 783 if len(list) > 0: 784 output.append(os.linesep) 785 786 # Format each object in the list 787 788 i = 0 789 790 for item in list: 791 792 indent = indentLevel * INDENT_DELTA 793 output.append(SPACES[: indent]) 794 795 if (type(item) == types.ListType or 796 type(item) == types.DictType or 797 isinstance(item, STAFMarshallingContext)): 798 output.append(formatObject(item, context, indentLevel, flags)) 799 elif item is None: 800 output.append(NONE_STRING) 801 else: 802 output.append(str(item)) 803 804 if i < (len(list) - 1): 805 output.append(ENTRY_SEPARATOR) 806 807 output.append(os.linesep) 808 809 indentLevel = indentLevel - 1 810 811 if len(list) > 0: 812 indent = indentLevel * INDENT_DELTA 813 output.append(SPACES[: indent]) 814 815 output.append(']') 816 817 elif type(obj) == types.DictType: 818 dict = obj 819 output.append('{') 820 indentLevel = indentLevel + 1 821 822 if len(dict) > 0: 823 output.append(os.linesep) 824 825 # Check if the map object has a map class key and if the context 826 # is valid and contains a map class definition for this map class. 827 # If not, treat as a plain map class. 828 829 if (dict.has_key(MAP_CLASS_NAME_KEY) and 830 (context is not None) and 831 isinstance(context, STAFMarshallingContext) and 832 context.hasMapClassDefinition(dict[MAP_CLASS_NAME_KEY])): 833 834 mapClass = context.getMapClassDefinition(dict[MAP_CLASS_NAME_KEY]) 835 836 # Determine maximum key length 837 838 maxKeyLength = 0 839 840 for theKey in mapClass.keys(): 841 theKeyString = theKey['key'] 842 843 if theKey.has_key(DISPLAY_NAME_KEY): 844 theKeyString = theKey[DISPLAY_NAME_KEY] 845 if len(theKeyString) > maxKeyLength: 846 maxKeyLength = len(theKeyString) 847 848 # Now print each object in the map 849 850 i = 0 851 852 for theKey in mapClass.keys(): 853 theKeyString = theKey['key'] 854 855 if theKey.has_key(DISPLAY_NAME_KEY): 856 theKeyString = theKey[DISPLAY_NAME_KEY] 857 858 indent = indentLevel * INDENT_DELTA 859 output.append('%s%s' % (SPACES[: indent], theKeyString)) 860 861 indent = maxKeyLength - len(theKeyString) 862 output.append('%s: ' % (SPACES[: indent])) 863 864 if dict.has_key(theKey['key']): 865 thisObj = dict[theKey['key']] 866 else: 867 thisObj = None 868 869 if (type(thisObj) == types.ListType or 870 type(thisObj) == types.DictType or 871 isinstance(thisObj, STAFMarshallingContext)): 872 output.append(formatObject(thisObj, context, indentLevel, flags)) 873 elif thisObj is None: 874 output.append(NONE_STRING) 875 else: 876 output.append(str(thisObj)) 877 878 if i < (len(dict) - 1): 879 output.append(ENTRY_SEPARATOR) 880 881 output.append(os.linesep) 882 i = i + 1 883 884 else: 885 # Determine maximum key length 886 887 maxKeyLength = 0 888 889 for theKeyString in dict.keys(): 890 if len(theKeyString) > maxKeyLength: 891 maxKeyLength = len(theKeyString) 892 893 # Now print each object in the map 894 895 i = 0 896 897 for theKeyString in dict.keys(): 898 indent = indentLevel * INDENT_DELTA 899 output.append('%s%s' % (SPACES[: indent], theKeyString)) 900 901 indent = maxKeyLength - len(theKeyString) 902 output.append('%s: ' % (SPACES[: indent])) 903 904 thisObj = dict[theKeyString] 905 906 if (type(thisObj) == types.ListType or 907 type(thisObj) == types.DictType or 908 isinstance(thisObj, STAFMarshallingContext)): 909 output.append(formatObject(thisObj, context, indentLevel, flags)) 910 elif thisObj is None: 911 output.append(NONE_STRING) 912 else: 913 output.append(str(thisObj)) 914 915 if i < (len(dict) - 1): 916 output.append(ENTRY_SEPARATOR) 917 918 output.append(os.linesep) 919 i = i + 1 920 921 indentLevel = indentLevel - 1 922 923 if len(dict) > 0: 924 indent = indentLevel * INDENT_DELTA 925 output.append(SPACES[: indent]) 926 927 output.append('}') 928 929 elif isinstance(obj, STAFMarshallingContext): 930 inputContext = obj 931 return formatObject(inputContext.getRootObject(), inputContext, 932 indentLevel, flags) 933 elif obj is None: 934 return NONE_STRING 935 else: 936 return str(obj) 937 938 return ''.join(output) 939 940 941# Used if called as script 942 943if (__name__ == "__main__"): 944 945 import sys 946 947 if len(sys.argv) < 4: 948 print "Usage: %s location service request" % sys.argv[0] 949 sys.exit(1) 950 951 location = sys.argv[1] 952 service = sys.argv[2] 953 request = sys.argv[3] 954 955 for requestPart in sys.argv[4:]: 956 request = request + " " + requestPart 957 958 try: 959 handle = STAFHandle("STAF/Client/Python") 960 except STAFException, e: 961 print "Error registering with STAF, RC: %d" % e.rc 962 sys.exit(e.rc) 963 964 result = handle.submit(location, service, request) 965 966 resultMC = unmarshall(result.result) 967 968 if (result.rc != 0): 969 print "Error submitting request, RC: %d" % result.rc 970 971 if (len(result.result) != 0): 972 print "Additional info: %s" % resultMC 973 974 else: 975 print "Response" 976 print "--------" 977 print resultMC 978 979 rc = handle.unregister() 980 981 sys.exit(rc) 982