/* -------------------------------------------------------------------------- */ /* */ /* DOCUMENTATION TOOL */ /* */ /* Frans Coenen */ /* */ /* Wednesday 19 September 2007 */ /* Revisised: Tuesday 16 October 2007, Mondat 1 Junr 2008 */ /* */ /* Department of Computer Science */ /* The University of Liverpool */ /* */ /* -------------------------------------------------------------------------- */ /** Transglobal express KTP documentation tool to document asp files. */ /* NOTES: 1. Everything gets converted to lower case for comparison purposes although this is not apparent from the output (whivh uses the original source). 2. Sting s=null; s=s+s; produces s = "nullnull"! 3. currentLine is a class variable used to temporerily hold line numbers, thus should usualy be reset to 0 when starting a new process. */ import java.io.*; import java.util.*; import javax.swing.*; class ASPdoc extends JFrame { // INPUT/OUTPUT FILE FIELDS /** Array of file names to be checked. */ private String[] fileNames = null; /** Alternative array of file paths. */ private File[] filePaths = null; /** Current input file name (used for error messaging. */ private String filename; /** Instance of BufferedReader class */ private BufferedReader fileInput = null; /** Output data file name. */ private File outputFileName = null ; /** Instance of PrintWriter class for file output. */ private PrintWriter fileOutput = null; // DATA STRUCTURES /** String array in which c urrent code is stored for processing. */ private String[] codeFile = null; /** Array of link labels. */ private LinkStruct[] links = null; /** Array of ASP structures. */ private ASPstruct[] aspFrags = null; /** Array of .asp function structures. */ private ASPfunctionStruct[] aspFunctions = null; /** Array of script structures. */ private ScriptStruct[] scriptFrags = null; /** Array of script function structures. */ private ScriptFunctionStruct[] scriptFunctions = null; // FLAGS /** Output links flag. */ private boolean outputLinksFlag = true; /** Output asp blocks flag. */ private boolean outputASPblocksFlag = true; /** Output asp functions flag. */ private boolean outputASPfuncsFlag = true; /** Output script blocks flag. */ private boolean outputScriptBlocksFlag = true; /** Output script functions flag. */ private boolean outputScriptFuncsFlag = true; // OTHER FIELDS /** The current line number used foe refficiency purposes (Reset for each new documentation process). */ private int currentLine = 0; /** The title inbetween the title tags in the ciurrentbinput file. */ private String title = null; /** The start comment if any. */ private String startComment = null; /** Text Area if using GUI interface. */ private JTextArea textArea = null; /* --------------------------------------------------- */ /* */ /* CONSTRUCTORS */ /* */ /* --------------------------------------------------- */ /** Defualt constructor used with GUI. */ public ASPdoc() { } /** One argumenmt constructor. @param tFile the file containing the list of field and method names to be checked. */ public ASPdoc(String[] fNames) { fileNames = fNames; } /* ---------------------------------------------------------------- */ /* */ /* S T A R T */ /* */ /* ---------------------------------------------------------------- */ /** Starts the documentation process, choosing btween a list of sting file names or paths. */ public void startDocumentation() { if (fileNames!=null) startDocumentation1(); else if (filePaths!=null) startDocumentation2(); else output("ERROR: no files specified"); } /** Starts documentation process where file list is in the form of a list of strings. */ private void startDocumentation1() { // Read files for (int fIndex=0;fIndexFILE. */ private void startDocumentation2() { // Read files for (int fIndex=0;fIndexThis is the heart of the process. */ private void processFile() { // Get title, if any, inbetween '' and '' tags if // available. int pos = findTitle(); // If title found have .html file, thus find opening comment on line // imediately after tag if available. Otherwise .asp file in // which case opening comment on second line. NOTR: Opening comments // are included by creator of the WWW site. pos = findComment(pos); //System.out.println("processFile 0: currentLine = " + currentLine); // Seasrch entire file looking for links ( if (pos1>=0) { int line = currentLine; int pos2 = findEndTag("/title",pos1+1); // Found end tag, get title (the enclosed string between the tags) if (pos2>=0) { title = getString(line,pos1+1,currentLine,pos2); pos = pos2; } // Otherwise error else output("ERROR " + filename + ": no closing tag!"); } else { pos = 0; currentLine = 0; } // Return return(pos); } /** Finds opening explanatory comment if available; this will be located immediately after the '' tag if HTML document or on second line (line number 1, first line is 0) if not .asp document, ot first line otherwise.

Note that comment can go over several lines. @return position in current line from where search is to continue. */ private int findComment(int pos) { // If title found have .html file, thus find comment on line imediately // after tag if available. if (title!=null) { int tempLineCounter = currentLine; int tempPos = findCommentAfterBodyTag(pos); if (tempPos>=0) pos=tempPos; else currentLine = tempLineCounter; } // Otherwise .asp file in which case opening comment on second line else if (codeFile[0].indexOf("<%")>=0) { currentLine=1; findHTMLcomment(0); currentLine = 0; } // Else html comment else { currentLine=0; findHTMLcomment(0); currentLine = 0; } // Return return(pos); } /** Attemots to find an HTML syle comment () located immediately after body start tag or starting after line 0 iks .asp page or on line 0 otherrwise; this is where any programmer comments should have been placed. Note that although there may be a title tag later in the code this may be followed by a body tag (and subsequent comment), in which case return to top of code and look for comments here. @param pos the location in the current line from where the search is to start. @return the current position in the line where the comment ends or -1. */ private int findCommentAfterBodyTag(int pos) { // Find tag pos = findStartTag("body",pos); // If found proceed, otherwise error if (pos>=0) pos = findHTMLcomment(pos); // No body tag therefore look back at top of code. else if (codeFile[0].indexOf("<%")>=0) { currentLine=1; pos = findHTMLcomment(0); currentLine = 0; if (pos<0) pos =-1; } // Else html comment else { currentLine=0; pos = findHTMLcomment(0); currentLine = 0; if (pos<0) pos =-1; } // Return return(pos); } /** Finds an HTML stylew comment () commencing search from currentLine in code. @param pos the location in the current line from where the search is to start. @retutn location of end of comment or -1 if no comment found. */ private int findHTMLcomment(int pos) { // Ignore empty lines (+1 becuse current line is where '' tag // was found (if appropriate). currentLine = findNextNonMTline(currentLine); //System.out.println("codeFile[currentLine] = " + codeFile[currentLine]); // Find open comment on discovered first non MT line int startPos = codeFile[currentLine].indexOf("=0) { // Found comment int startLine = currentLine; int endPos = findChar('>',startPos+2); startComment = getString(startLine,startPos+2,currentLine,endPos); //System.out.println("startComment = " + startComment); return(endPos); } // Otherwise no comment else return(-1); } /* ---------------------------------------------------------------- */ /* */ /* L I N K S */ /* */ /* ---------------------------------------------------------------- */ /** Identifies links (URLs) in given input file. @param pos position in line indicated by tempLineCounter from where searching is to commence. @param tempLineCounter line input file form where search should begin. */ private void findLinks(int pos) { int tempLineCounter = currentLine; // Count links int numLinks = countLinks(0,pos); //System.out.println("numLinks = " + numLinks); // If links found define links structure if (numLinks>0) { links = new LinkStruct[numLinks]; for(int i=0;i'tags and dimension links array. @counter the '< * HREF * >' tags encountered so far. @param pos the location in the current line from where the search is to start. */ private int countLinks(int counter, int pos) { // Search for '' if (startPos>=0) { int startLine = currentLine; int endPos = findChar('>',startPos+1); // If found get string between '<' and '>' and test contents. if (endPos>=0) { String s = getString(startLine,startPos+2,currentLine,endPos); String tempS = s.toLowerCase().trim(); int i = tempS.indexOf("href"); //System.out.println("tempS = " + tempS); if (i==0) return(countLinks(counter+1,endPos+1)); else return(countLinks(counter,endPos+1)); } // No end pos essentially an error in the input file else return(counter); } // No open '<' tag operator found else return(counter); } /** Find links ('' tags). @param pos the location in the current line from where the search is to start. @param index the current index in to the links array. */ private void findLink(int pos, int index) { // Search for '' if (startPos>=0) { int startLine = currentLine; int[] end = findEndOfTag(startLine,startPos+1); int endPos = end[1]; // If found '>' get contents and check that includes 'HREF'. if (endPos>=0) { int endLine = end[0]; String s = getString(startLine,startPos+2,endLine,endPos); String tempS = s.toLowerCase().trim(); int i = tempS.indexOf("href"); //System.out.println("tempS = " + tempS); if (i==0) { String label = checkForSpecialChars(getValue(s)); // Check for no reference label if (label.length()==0) label=null; // Set and increment index links[index].setLineNumber(currentLine); links[index].setLinkLabel(label); index=index+1; } findLink(endPos+1,index); } else output("ERROR " + filename + ": No '>' paired " + "with '<' on line " + startLine + "!"); } } /** Finds the closing '>' matching an opening '<'. @param startLine the line number in the code file where the '<' is located @return two element array reprresenting the end line number and end position in that line. */ private int[] findEndOfTag(int startLine, int startPos) { int[] end = {-1,-1}; int n = 1; for (int i=startLine;i' " + " found for .asp fragement starting on line " + (aspFrags[index].getStartLineNum()+1) + "!"); } /** Collect ASP block commnets located between start and end of ASP block but excluding functions.

Does this by processing ASPstruct data structure. The varibale j is the index into the aspFunctions structure, we do not want to include comments with function blocks. */ private void collectASPblockComments() { // Loop through identified .asp fragments in ASPstruct data structure int j=0; // aspFunction array index for (int i=0;i=aspFunctions.length)) { // Search for commnets between blockLN and blockEnd String s = findASPcomments(blockLN,blockEnd); aspFrags[i].setNote(s); //System.out.println("blockLN = " + blockLN + ", blockEnd = " + blockEnd + "\n" + s); } else j=collectASPblockComments(aspFrags[i],blockLN,blockEnd,j); } } /** Collects ASP block comments for given block where functions are included. @param linkref The reference to the current ASP block. @param blockLN The current block line number starting with the block start line number. @param blockEnd The block end line number. @param j The current index into the ASP function structure. @return The updated index sofar into the ASP function structure. */ private int collectASPblockComments(ASPstruct linkRef, int blockLN, int blockEnd, int j) { String s = null; // Get start of first function int funcStart = aspFunctions[j].getStartLineNum(); // Process block missing out ASP functions while (funcStart=0) && (endPos>=0)) { if (s==null) getString(startLine,startPos+4,currentLine,endPos); else s = s + getString(startLine,startPos+4,currentLine,endPos); } // Repear i= currentLine; } // Return return(s); } /* ---------------------------------------------------------------- */ /* */ /* A S P F U N C T I O N S */ /* */ /* ---------------------------------------------------------------- */ /* Series of methods to identify ASP functions. */ /** Commences identification of functions contained with .asp fragments; identified by processing identified fragments. */ private void countASPfunctions() { int tempCurrentLine = currentLine; int counter = 0; // Loop through identified .asp fragments for (int i=0;i=0) { //System.out.println("countFunctions/5"); //System.out.println("Function currentLine (start) = " + i); counter++; lookingForEnd=true; } } } // End, last line can only have an "end function" so ignore return(counter); } /** Commences process of dentifing details of functions contained in .asp fragments. */ private void idASPfunctions() { int tempCurrentLine = currentLine; int index = 0; // Loop through identified .asp fragments for (int i=0;i=0) && (!isCommentedOut(startLine-1))) { //System.out.println("checkForFunction/4"); //System.out.println("lookingForEnd = " + lookingForEnd + ", s = " + s + //", startLine = " + startLine + ", index = " + index); //System.out.println("startLine = " + startLine); if (isCommentedOut(startLine-1)) aspFunctions[index].setCommentedOutFlag(true); getASPfunctionDetails(index,startLine,pos+8); found = true; } } // If no 'function' or 'end' keyword found return default return(found); } /** Searches for end of asp function in given line. @param s the given string. @return trure if found 'end function, false otherwise. */ private boolean findEndASPfunction(String s) { int pos = s.indexOf("end"); // Check if end found if (pos>=0) { // Get rest of line s = s.substring(pos+3).trim(); if (s.indexOf("function")==0) return(true); } // Default return return(false); } /** Gets asp functions details assuming name is on same line as function keyword. @param index the current function array index. @param startLine the line in the source code where the current .asp fragment starts. @param startPos the location in the line in the source code where the current .asp fragment starts. */ private void getASPfunctionDetails(int index, int startLine, int startPos) { // Set start of function line number in structure. aspFunctions[index].setStartLineNum(startLine); // Try and find '(' on current line currentLine = startLine; //System.out.println("currentLine = " + currentLine + ", startPos = " + startPos + //", line = " + codeFile[currentLine] + ",index = " + index); int pos = findChar('(',startPos); //System.out.println("pos = " + pos); // Get string if (pos>=0) { String s = getString(startLine,startPos,currentLine,pos); s = s.trim(); //System.out.println("Label = '" + s + "'"); aspFunctions[index].setLabel(s); // Get arguments aspFunctions[index].setArguments(getArguments(startLine,pos+1)); // Now get preceding note s = codeFile[startLine-1]; pos = s.indexOf('\''); if (pos>=0) { s = s.substring(pos+1); aspFunctions[index].setNote(s); } } // Error else output("ERROR " + filename + ": No function name " + "found for function starting on line " + (startLine+1)); } /* ---------------------------------------------------------------- */ /* */ /* S C R I P T F R A G M E N T S */ /* */ /* ---------------------------------------------------------------- */ /** Count 'script' fragments indicated by a '' paired " + "with ''. @param pos the location in the current line from where the search is to start. @param index the current index into the links array. */ private void findScriptFragEnd(int pos, int index) { int endPos = findString("",pos); // If found cupdate structure abd repeate if (endPos>=0) { //System.out.println("findScriptFragEnd: endPos = " + endPos + ", currentLine = " + currentLine); scriptFrags[index].setEndLineNum(currentLine,endPos); findScriptFragStart(endPos+1,index+1); } // Otherwise no closing tag found else output("ERROR " + filename + ": No closing " + "'' found for script block starting on line " + (aspFrags[index].getStartLineNum()+1) + "!"); } /* ---------------------------------------------------------------------- */ /* */ /* C O U N T S C R I P T F U N C T I O N S */ /* */ /* ---------------------------------------------------------------------- */ /* Java script function name() { } VBScript function name end function. */ /** Commences process of counting the number of functions in identified scripts and dimensioning the script functions afrray.

Functions may be VBScript of JavaScript functions. */ private void countScriptFunctions() { int tempCurrentLine = currentLine; int counter = 0; // Loop through identified script fragments for (int i=0;i=0;i--) { startPos = codeFile[i].indexOf("/*"); if (startPos>=0) break; } // Get comment string String s = getString(i,startPos+2,endLine,endPos); s = s.trim(); scriptFunctions[index].setNote(s); } /** Finds the end of a function when dealing with java script. @param startLine the line number in the code file where the function of interest starts. @return the end line number. */ private int findEndOfFunction(int startLine) { boolean notStart = false; int n = 0; for (int i=startLine;i Foramt may be: (i) 'Fuction name ... End Function', or (ii) 'function name(args) ... End Function' current script fragment. @param index the function array index sofar. @param type language the 'langage' label, e.g. VBScript. @param startLine the line in the source code where the current script fragment starts. @param endLine the line in the source code where the current .asp fragment endss. @return the updates index. */ private int idScriptFunctionsVB(int index, String typeLang, int startLine, int endLine) { boolean lookingForEnd = false; String[] endFunction = {"end","function"}; // Loop for (int i=startLine;iArgumdemts are assumed tlo be contained bwtween '(' and ')' characters and seperated by a ',' characters. @param startLine the line number in the code file where the opening '(' has been found. @param startPos the position in the "startLined" immediately after the opening '('. @return list of arguments, or "null" if there are not any. */ private String[] getArguments(int startLine, int startPos) { // Count arguments int size = countArguments(startLine,startPos); if (size==0) return(null); String[] arguments = new String[size]; // Find closing ')' character currentLine = startLine; int endPos = findChar(')',startPos); // Find arguments int index=0; if (endPos>=0) { int endLine = currentLine; String s = getString(startLine,startPos,endLine,endPos); //System.out.println("s = " + s); // look for ',' characters int i=0; while (true) { int pos = s.indexOf(',',i); //System.out.println("startpos = " + startPos + ", comma pos = " + pos); if (pos<0) { String arg = s.substring(i,s.length()); arg = arg.trim(); if (arg.length()>0) //System.out.println("END '" + arg + "', length = " + arg.length()); arguments[index]=arg; break; } String arg = s.substring(i,pos-1); arg = arg.trim(); arguments[index] = arg; //System.out.println("'" + arg + "'"); i=pos+1; } } // Otherwise something has gone wrong but error message already output // during counting // End return(arguments); } /** Counts number of arguments associated with identified function. @param startLine the line number in the code file where the opening '(' has been found. @param startPos the position in the "startLined" immediately after the opening '('. @return the number of arguments in the function, or "null". */ private int countArguments(int startLine, int startPos) { int counter=0; // Find closing ')' character currentLine = startLine; int endPos = findChar(')',startPos); // Find arguments if (endPos>=0) { int endLine = currentLine; String s = getString(startLine,startPos,endLine,endPos); // look for ',' characters int i=0; while (true) { int pos = s.indexOf(',',i); if (pos<0) { String arg = s.substring(i,s.length()); arg = arg.trim(); if (arg.length()>0) counter++; break; } counter++; i=pos+1; } } // Otherwise something has gone wrong else output("ERROR " + filename + ": no closing ')' " + "characyter found for function on " + (startLine+1) + "!"); // Return return(counter); } /* ------ UTILITIES ------ */ /** Determines if function is commented out.

A function is commented out if it is preceeded by a before the start of the function. */ private boolean isCommentedOut(int startLine) { //System.out.println("startLine = " + startLine); for (int i=startLine;i>=0;i--) { int n = isCommentedOut(codeFile[i]); if (n==1) return(true); if (n==-1) return(false); } // End return(false); } /* Checks given line for an open comment processing it in reverse. @param s the given string/line. @return 1 if open comment found, -1 if close comment found, 0 if neither. */ private int isCommentedOut(String s) { //System.out.println("s = " + s); for(int i=s.length()-1;i>=0;i--) { if (s.charAt(i)=='>') return(-1); if ((s.charAt(i)=='!') && (i>0) && (s.charAt(i-1)=='<')) return(1); } // Default return(0); } /* ------------------------------------- */ /* */ /* STRING MANIPUILATION */ /* */ /* ------------------------------------- */ /** Find specified string, e.g. 'currentLine filed. */ private int findString(String searchS, int pos) { // Check for end of file, if found return -1 if (currentLine>=codeFile.length) return(-1); // Check first line (convert to lower case). String s = codeFile[currentLine].substring(pos); int startPos = s.toLowerCase().indexOf(searchS); // If found return start pos, otherwise increment line if (startPos>=0) return(startPos); else currentLine++; // Continue search for (;currentLine=0) break; } // End return(startPos); } /** Find specified string, e.g. '