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