# docFunctions.py
#
# by Arthur Kevin McGrath
#
# The functions in this file create documentation
# for the various WebSphere Application Server
# script objects
#
# Much of this code has fileObject.write(DIAGNOSTIC comments
# If you have trouble, remove the comments. Let the DIAGNOSTICs execute
# You will get about a megabyte and a half of output
"""
Create documentation for the various WebSphere Application Server script objects. Each AdminTask command is documented in XML format. The command description, the list of parameters, and the list of steps for each command all appear in one place. Display the output on your browser.
"""
import AdminTask
# documentAdminTask
# prints available documentation for all AdminTask commands
# parameters
# fileName - String - all output goes to this file
def documentAdminTask( fileName ):
"""
Prints available documentation for all AdminTask commands.
Prints commands in alphabetical order withour regard to group membership
parameters
fileName - String - all output goes to this file
"""
f = open( fileName, 'w' )
cmdList = AdminTask.help( '-commands' ).splitlines()
# The first two lines are not AdminTask commands
#if len(cmdList) > 2:
#del cmdList[0]
#del cmdList[1]
f.write( "\n\n" )
# For DIAGNOSTICS ONLY
#writeUnprocessedList( f, cmdList )
for cmd in cmdList:
parseLinePrintHelp( f, cmd )
f.write( "\n\n\n" )
f.close()
return
# documentAdminTaskByCategory
# Prints available documentation for all AdminTask commands.
# Commands are organized by AdminTask group.
# Some commands may be members of more than one group.
# parameters
# fileName - String - all output goes to this file
def documentAdminTaskByCategory( fileName ):
"""
Prints available documentation for all AdminTask commands.
Commands are organized by AdminTask group.
Some commands may be members of more than one group.
parameters
fileName - String - all output goes to this file
"""
# We want to filter out any blank lines. In addition,
# there is apparently one meaningless group name
# That name is 'null' It has no known members
# It is also the shortest known group name
# If IBM ever creates a legitimate group
# that only has four (or fewer) characters,
# this filtering technique could seriously
# blow up in our faces.
MiminumLengthOfGroupName = 4
f = open( fileName, 'w' )
groupList = AdminTask.help( '-commandGroups' ).splitlines()
f.write( "\n\n" )
# For DIAGNOSTICS ONLY
#writeUnprocessedList( f, cmdList )
for groupLine in groupList:
# disregard blank lines
if len(groupLine) > MiminumLengthOfGroupName:
# disregard any warning lines
if groupLine.find( 'WASX' ) == 0:
continue
if groupLine.find( 'Commands:' ) == 0:
continue
lineTokens = groupLine.split( '-' )
groupName = lineTokens[0].strip()
if len(groupName) > MiminumLengthOfGroupName:
cmdList = AdminTask.help( groupName ).splitlines()
f.write( "\n\n" )
for cmd in cmdList:
parseLinePrintHelp( f, cmd )
f.write( "\n\n" )
f.write( "\n\n\n" )
f.close()
return
#writeUnprocessedList
# This is a DIAGNOSTIC method meant for internal use only
# write each line of the list exactly as IBM gave it to us
# If you think we are parsing IBM output incorrectly,
# this method will show you the raw data that we are parsing
#parameters:
# fileObject - this must be an file that was opened in 'w' mode
# cmdList - List - the list of lines returned by IBM help() from a script object
def writeUnprocessedList( fileObject, cmdList ):
for cmd in cmdList:
# write the short command description
fileObject.write( '\n- - >' + cmd + '< - -' )
fileObject.write( '\n#$! - - - #$! - - - #$! - - - #$! - - -\n\n' )
fileObject.write( ' End of Summary\n' )
fileObject.write( '\n#$! - - - #$! - - - #$! - - - #$! - - -\n\n' )
#parseLinePrintHelp
#split one line of IBM help into tokens. We expect the first token to be the name of a function
#ask for help for that function. Take reasonable precautions to work around IBM screwups
#parameters:
# fileObject - this must be an file that was opened in 'w' mode
# cmd - String - one of the lines returned by IBM help() from a script object
def parseLinePrintHelp( fileObject, cmd ):
# parse the command name out of the description
c = cmd.split()
# get help specific to that command
# but first, protect ourselves because IBM was sloppy
# when it created online help
if len(c) > 2: # IBM returns some random blank lines
if c[1] == '-': # IBM also returns lines with random text
helpArray = AdminTask.help(c[0]).splitlines()
# write the AdminTask command
#fileObject.write( '\n\n\n' + c[0] + '\n' )
fileObject.write( '\n\n\n' + helpArray[i] + '< - - DEBUG parseLinePrintHelp()\n' )
# END DIAGNOSTIC!!!!!
beginning = helpArray[i][:4]
if beginning != 'WASX':
possibleTokens = helpArray[i].split(':')
if len( possibleTokens ) > 1: #modified 2009-02-20 to fix problems catching description line -- AKM
# There has to be at least two tokens before we can claim
# we have found the Description part of the help
# We found the start of the description section
# Enter the state machine for this command
# Slice off any lines we have already processed
processDescription( fileObject, helpArray[i:], c[0] )
fileObject.write( '\n' )
return
# - - - - - AdminTask State Mchine Starts Here - - - - -
#processDescription
# extract the description from the array of lines
# Parse line. All tokens after colon are description
# So are all lines that follow
# Exit trigger string: 'Target object:'
# Next state: processTarget()
#parameters:
# fileObject - a File that has been opened fo r'w' mode
# initialArray - List of Strings - the text IBM returns from AdminTask.help()
# adminTaskCommand - If this command has steps, we need this to get help on the steps
def processDescription( fileObject, initialArray, adminTaskCommand ):
description = ''
middleList = []
exitTrigger = 'Target object'
exitTriggerMandatory = '*Target object'
# DIAGNOSTIC!!!!!
#fileObject.write( '\n\t- - initialArray[0] - >' + initialArray[0] + '< - - DEBUG processDescription()\n' )
#fileObject.flush()
# END DIAGNOSTIC!!!!!
# if the first line does not hold a description, we should not be here
tokens = initialArray[0].split( ':' )
if tokens[0].strip() == "Description":
description = tokens[1].strip()
else:
#we failed an assertion. See above
# DIAGNOSTIC!!!!!
fileObject.write( ' - - >' + adminTaskCommand + ' has a problem' + '< - - DEBUG processDescription()\n' )
fileObject.write( '\n\t- - initialArray[0] - >' + initialArray[0] + '< - - DEBUG processDescription()\n' )
fileObject.flush()
# END DIAGNOSTIC!!!!!
raise AssertionError( "There was no Description in the first line of the array we received from our caller for " + adminTaskCommand )
arbitraryMinimumLength = 4
# Due to IBM sloppiness, there might be additional lines in the description
for i in range( 1, len(initialArray) ):
# DIAGNOSTIC!!!!!
#fileObject.write( '\n\t- - initialArray[' + str(i) + '] - >' + initialArray[i] + '< - - DEBUG processDescription()\n' )
# END DIAGNOSTIC!!!!!
# Somewhat arbitrary here. The intent of the next test is
# to screen out blank lines
if len(initialArray[i]) > arbitraryMinimumLength:
# see if we found the exit trigger
tokens = initialArray[i].split(':')
if len( tokens ) > 1:
if (tokens[0].strip() == exitTrigger) or (tokens[0].strip() == exitTriggerMandatory):
description = sanitizeText( description )
fileObject.write( " description=\"" + description + "\" >\n" )
#DIAGNOSTIC
#fileObject.flush()
#END DIAGNOSTIC
# slice off the strings we have already processed
# Target object will need to process the current line of the array
processTarget(fileObject, initialArray[i:], adminTaskCommand )
return
# We might have blank lines OR
# we might have more text for the description
tokens = initialArray[i].split()
tempLine = ""
for i in range( len(tokens) ):
tempLine = tempLine + " " + tokens[i]
description = description + " " + tempLine
# If we get here, there was nothing that qualified as an exit trigger. We don't seem to have a Target Object after us
raise AssertionError( "There was no " + exitTrigger + " after the Description in the array we received from our caller" )
#processTarget
# extract the target object (if any) from the array of lines
# When we get to here, we expect the Target Object to be
# in line 0 of the array of strings
# We also assume that there is NEVER more than one valid line of Target Object data
# Exit trigger: Arguments
# Next state: processArguments()
#parameters:
# fileObject - a File that has been opened for 'w' mode
# arrayOfLines - array of Strings - the text IBM returns from AdminTask.help()
# adminTaskCommand - If this command has steps, we need this to get help on the steps
def processTarget( fileObject, arrayOfLines, adminTaskCommand ):
targetString = 'Target object'
targetStringMandatory = '*Target object'
exitTrigger = "Arguments"
tagList = arrayOfLines[0].split(':')
# DIAGNOSTIC!!!!!
#fileObject.write( '\n\t- - arrayOfLines[0] - >' + arrayOfLines[0] + '< - - DEBUG processTarget()\n' )
fileObject.flush()
# END DIAGNOSTIC!!!!!
#DIAGNOSTIC!!!!
#print " should say - - >" + targetString + "< - -"
#print " - - >" + tagList[0].strip() + "< - -"
#END DIAGNOSTIC!!!!
if tagList[0].strip() == targetString:
fileObject.write( ' ' )
elif tagList[0].strip() == targetStringMandatory:
fileObject.write( ' ' )
else:
raise AssertionError( "Could not find " + targetString + " at the beginning of the first line of the arrayOfLines" )
# This loop is necessary because some idiot at IBM used an unnecessary extra colon
# in the middle of a Target Object string
for i in range( 1, len(tagList) ):
text = tagList[i].strip()
if text != "None":
text = sanitizeText( text )
fileObject.write(text )
# strip off any blank lines that follow
for i in range( 1, len(arrayOfLines) ):
# DIAGNOSTIC!!!!!
#fileObject.write( '\n\t- - arrayOfLines[' + str(i) + '] - >' + arrayOfLines[i] + '< - - DEBUG processTarget()\n' )
#fileObject.flush()
# END DIAGNOSTIC!!!!!
tagList = arrayOfLines[i].split( ':' )
# DIAGNOSTIC!!!!!
#fileObject.write( '\n\t- - tagList - >length ' )
#fileObject.write( str(len( tagList )) )
#fileObject.write( ' items< - - DEBUG processTarget()\n' )
#for tag in tagList:
#fileObject.write( '\t\t- - >' + tag + '< - - DEBUG processTarget()\n' )
#fileObject.flush()
# END DIAGNOSTIC!!!!!
# did we just reach our exit trigger?
if tagList[0].strip() == exitTrigger:
# Yes. Call the next state.
# The next state does not expect anything on the same line as the exit trigger
fileObject.write( '\n' )
processArguments( fileObject, arrayOfLines[ i+1: ], adminTaskCommand )
return
# If we drop out of the FOR loop without calling processArguments()
# something is seriously wrong
raise AssertionError( "We went through processTarget() without ever finding the exitTrigger -- " + exitTrigger )
#processArguments
# extract the description from the array of lines
# Exit trigger: Steps
# Next state: processSteps()
#parameters:
# fileObject - a File that has been opened fo r'w' mode
# arrayOfLines - array of Strings - the text IBM returns from AdminTask.help()
# adminTaskCommand - If this command has steps, we need this to get help on the steps
def processArguments( fileObject, arrayOfLines, adminTaskCommand ):
exitTrigger = "Steps"
fileObject.write( " \n" )
# parse each line for either:
# the exit trigger, or
# a name / description pair
for i in range( len(arrayOfLines) ):
# DIAGNOSTIC!!!!!
#fileObject.write( '\n\t- - arrayOfLines[' + str(i) + '] - >' + arrayOfLines[i] + '< - - DEBUG processArguments()\n' )
#fileObject.flush()
# END DIAGNOSTIC!!!!!
possibleTokens = arrayOfLines[i].split( ':' )
if len( possibleTokens ) > 1 and possibleTokens[0] == exitTrigger:
# we found our exit trigger
fileObject.write( " \n" )
processSteps( fileObject, arrayOfLines[ i+1: ], adminTaskCommand )
return
else:
possibleTokens = arrayOfLines[i].split( '-' )
if len( possibleTokens ) == 2:
# we have an argument / description
arg = possibleTokens[0].strip()
description = possibleTokens[1].strip()
description = sanitizeText( description )
if arg[0] == "*":
fileObject.write( " \n" )
else:
# DIAGNOSTIC
#if description.find( "groupOfNames" ) > 0:
#print "- ->" + description + "< - -\n"
#print "- s ->" + description.replace( "\"", "$quot;" ) + "< - s -\n"
# DIAGNOSTIC
fileObject.write( " \n" )
#processSteps
# extract the description from the array of lines
#parameters:
# fileObject - a File that has been opened fo r'w' mode
# arrayOfLines - array of Strings - the text IBM returns from AdminTask.help()
# adminTaskCommand - If this command has steps, we need this to get help on the steps
def processSteps( fileObject, arrayOfLines, adminTaskCommand ):
arbitraryMinimumLineLength = 3
# this variable is a state machine with the Step processing state. Legal values are:
# 0 - Name of Step state
# 1 - Description of Step state
# 2 - Are arguments part of a collection state
# 3 - Arguments of Step state
# 4 - Finished
stepProcessingState = 0
fileObject.write( " \n" )
for line in arrayOfLines:
# DIAGNOSTIC!!!!!
#fileObject.write( '\n\t- - current line - >' + line + '< - - DEBUG processSteps()\n' )
# END DIAGNOSTIC!!!!!
possibleTokens = line.split( '-' )
if len( possibleTokens ) == 2:
stepHelpRaw = AdminTask.help( adminTaskCommand, possibleTokens[0].strip() )
stepHelp = stepHelpRaw.splitlines()
stepProcessingState = 0
collectionValue=0
for i in range( len(stepHelp) ):
if stepProcessingState == 0: # step name line
stepNameList = stepHelp[i].split(':')
fileObject.write( " " + stepHelp[i] + "< - - -->\n" )
#fileObject.flush()
# End of DIAGNOSTIC line
descriptionTokens = stepHelp[i].split(':')
if len(descriptionTokens) > 1:
d = ""
for n in range( len(descriptionTokens) ):
if n == 0:
d = descriptionTokens[n].strip()
else:
d = d + " " + descriptionTokens[n].strip()
d = sanitizeText( d )
fileObject.write( "\n description=\"" + d + "\" " )
fileObject.write( ">\n" )
stepProcessingState += 1
elif stepProcessingState == 2: # are the arguments part of a collection
collectionTokens = stepHelp[i].split(':')
if len(collectionTokens) > 1:
if collectionTokens[1].strip() == "No":
collectionValue=0
stepProcessingState += 1
if collectionTokens[1].strip() == "no":
collectionValue=0
stepProcessingState += 1
if collectionTokens[1].strip() == "Yes":
collectionValue=1
stepProcessingState += 1
if collectionTokens[1].strip() == "yes":
collectionValue=1
stepProcessingState += 1
elif stepProcessingState == 3: # arguments element starts here
fileObject.write( " 0:
fileObject.write( " collection=\"true\" " )
fileObject.write( ">\n" )
stepArguments( fileObject, stepHelp[4:] )
fileObject.write( " \n \n" )
stepProcessingState += 1
elif stepProcessingState == 4: # finished
#show the problem line as an XML comment
#fileObject.write( " \n" )
pass
else:
# something is seriously wrong
raise AssertionError( "In processSteps(), we have an illegal value for stepProcessingState -- " + str(stepProcessingState) )
fileObject.write( " \n" )
#stepArguments
# parse any arguments that are part of an AdminTask step
#parameters:
# fileObject - a File that has been opened fo r'w' mode
# stepHelp - an array of strings that have one argument per string
def stepArguments( fileObject, stepHelp):
# everything below here is zero to an infinite number of arguments
arbitraryMinimumLineLength = 3
for i in range( len(stepHelp) ):
text = stepHelp[i].strip()
if len(text) > arbitraryMinimumLineLength:
if text != 'None':
if len(text) > arbitraryMinimumLineLength:
argumentParts = text.split( '-' )
if len(argumentParts) > 1:
if argumentParts[0][0] == '*':
fileObject.write( " 1:
fileObject.write( "/>\n" )
def sanitizeText( unsanitaryText ):
pass
sanitizedText = unsanitaryText.replace( "\"", "$quot;" )
sanitizedText = sanitizedText.replace( "<", "$lt;" )
sanitizedText = sanitizedText.replace( ">", "$gt;" )
sanitizedText = sanitizedText.replace( "&", "$amp;" )
sanitizedText = sanitizedText.replace( "\'", "$apos;" )
#DIAGNOSTIC
#if sanitizedText != unsanitaryText:
#print " - - >" + unsanitaryText + "< - -\n"
#print " - - >" + sanitizedText + "< - -\n"
#End DIAGNOSTIC
return sanitizedText
# - - - - - AdminTask State Mchine Ends Here - - - - -
# main method starts here
if __name__ == "main":
print "Running standalone . . ."
else:
print __name__ , "module is loaded"