diff options
Diffstat (limited to 'src/jdiff/Options.java')
-rwxr-xr-x | src/jdiff/Options.java | 443 |
1 files changed, 443 insertions, 0 deletions
diff --git a/src/jdiff/Options.java b/src/jdiff/Options.java new file mode 100755 index 0000000..748da7c --- /dev/null +++ b/src/jdiff/Options.java @@ -0,0 +1,443 @@ +package jdiff; + +import java.io.*; +import java.util.*; +import com.sun.javadoc.*; + +/** + * Class to handle options for JDiff. + * + * See the file LICENSE.txt for copyright details. + * @author Matthew Doar, mdoar@pobox.com + */ +public class Options { + + /** Default constructor. */ + public Options() { + } + + /** + * Returns the "length" of a given option. If an option takes no + * arguments, its length is one. If it takes one argument, its + * length is two, and so on. This method is called by Javadoc to + * parse the options it does not recognize. It then calls + * {@link #validOptions} to validate them. + * <blockquote> + * <b>Note:</b><br> + * The options arrive as case-sensitive strings. For options that + * are not case-sensitive, use toLowerCase() on the option string + * before comparing it. + * </blockquote> + * + * @param option a String containing an option + * @return an int telling how many components that option has + */ + public static int optionLength(String option) { + String opt = option.toLowerCase(); + + // Standard options + if (opt.equals("-authorid")) return 2; + if (opt.equals("-versionid")) return 2; + if (opt.equals("-d")) return 2; + if (opt.equals("-classlist")) return 1; + if (opt.equals("-title")) return 2; + if (opt.equals("-docletid")) return 1; + if (opt.equals("-evident")) return 2; + if (opt.equals("-skippkg")) return 2; + if (opt.equals("-skipclass")) return 2; + if (opt.equals("-execdepth")) return 2; + if (opt.equals("-help")) return 1; + if (opt.equals("-version")) return 1; + if (opt.equals("-package")) return 1; + if (opt.equals("-protected")) return 1; + if (opt.equals("-public")) return 1; + if (opt.equals("-private")) return 1; + if (opt.equals("-sourcepath")) return 2; + + // Options to control JDiff + if (opt.equals("-apiname")) return 2; + if (opt.equals("-oldapi")) return 2; + if (opt.equals("-newapi")) return 2; + + // Options to control the location of the XML files + if (opt.equals("-apidir")) return 2; + if (opt.equals("-oldapidir")) return 2; + if (opt.equals("-newapidir")) return 2; + if (opt.equals("-usercommentsdir")) return 2; + + + // Options for the exclusion level for classes and members + if (opt.equals("-excludeclass")) return 2; + if (opt.equals("-excludemember")) return 2; + + if (opt.equals("-firstsentence")) return 1; + if (opt.equals("-docchanges")) return 1; + if (opt.equals("-packagesonly")) return 1; + if (opt.equals("-showallchanges")) return 1; + + // Option to change the location for the existing Javadoc + // documentation for the new API. Default is "../" + if (opt.equals("-javadocnew")) return 2; + // Option to change the location for the existing Javadoc + // documentation for the old API. Default is null. + if (opt.equals("-javadocold")) return 2; + + if (opt.equals("-baseuri")) return 2; + + // Option not to suggest comments at all + if (opt.equals("-nosuggest")) return 2; + + // Option to enable checking that the comments end with a period. + if (opt.equals("-checkcomments")) return 1; + // Option to retain non-printing characters in comments. + if (opt.equals("-retainnonprinting")) return 1; + // Option for the name of the exclude tag + if (opt.equals("-excludetag")) return 2; + // Generate statistical output + if (opt.equals("-stats")) return 1; + + // Set the browser window title + if (opt.equals("-windowtitle")) return 2; + // Set the report title + if (opt.equals("-doctitle")) return 2; + + return 0; + }//optionLength() + + /** + * After parsing the available options using {@link #optionLength}, + * Javadoc invokes this method with an array of options-arrays, where + * the first item in any array is the option, and subsequent items in + * that array are its arguments. So, if -print is an option that takes + * no arguments, and -copies is an option that takes 1 argument, then + * <pre> + * -print -copies 3 + * </pre> + * produces an array of arrays that looks like: + * <pre> + * option[0][0] = -print + * option[1][0] = -copies + * option[1][1] = 3 + * </pre> + * (By convention, command line switches start with a "-", but + * they don't have to.) + * <p> + * <b>Note:</b><br> + * Javadoc passes <i>all</i>parameters to this method, not just + * those that Javadoc doesn't recognize. The only way to + * identify unexpected arguments is therefore to check for every + * Javadoc parameter as well as doclet parameters. + * + * @param options an array of String arrays, one per option + * @param reporter a DocErrorReporter for generating error messages + * @return true if no errors were found, and all options are + * valid + */ + public static boolean validOptions(String[][] options, + DocErrorReporter reporter) { + final DocErrorReporter errOut = reporter; + + // A nice object-oriented way of handling errors. An instance of this + // class puts out an error message and keeps track of whether or not + // an error was found. + class ErrorHandler { + boolean noErrorsFound = true; + void msg(String msg) { + noErrorsFound = false; + errOut.printError(msg); + } + } + + ErrorHandler err = new ErrorHandler(); + if (trace) + System.out.println("Command line arguments: "); + for (int i = 0; i < options.length; i++) { + for (int j = 0; j < options[i].length; j++) { + Options.cmdOptions += " " + options[i][j]; + if (trace) + System.out.print(" " + options[i][j]); + } + } + if (trace) + System.out.println(); + + for (int i = 0; i < options.length; i++) { + if (options[i][0].toLowerCase().equals("-apiname")) { + if (options[i].length < 2) { + err.msg("No version identifier specified after -apiname option."); + } else if (JDiff.compareAPIs) { + err.msg("Use the -apiname option, or the -oldapi and -newapi options, but not both."); + } else { + String filename = options[i][1]; + RootDocToXML.apiIdentifier = filename; + filename = filename.replace(' ', '_'); + RootDocToXML.outputFileName = filename + ".xml"; + JDiff.writeXML = true; + JDiff.compareAPIs = false; + } + continue; + } + if (options[i][0].toLowerCase().equals("-apidir")) { + if (options[i].length < 2) { + err.msg("No directory specified after -apidir option."); + } else { + RootDocToXML.outputDirectory = options[i][1]; + } + continue; + } + if (options[i][0].toLowerCase().equals("-oldapi")) { + if (options[i].length < 2) { + err.msg("No version identifier specified after -oldapi option."); + } else if (JDiff.writeXML) { + err.msg("Use the -apiname or -oldapi option, but not both."); + } else { + String filename = options[i][1]; + filename = filename.replace(' ', '_'); + JDiff.oldFileName = filename + ".xml"; + JDiff.writeXML = false; + JDiff.compareAPIs = true; + } + continue; + } + if (options[i][0].toLowerCase().equals("-oldapidir")) { + if (options[i].length < 2) { + err.msg("No directory specified after -oldapidir option."); + } else { + JDiff.oldDirectory = options[i][1]; + } + continue; + } + if (options[i][0].toLowerCase().equals("-newapi")) { + if (options[i].length < 2) { + err.msg("No version identifier specified after -newapi option."); + } else if (JDiff.writeXML) { + err.msg("Use the -apiname or -newapi option, but not both."); + } else { + String filename = options[i][1]; + filename = filename.replace(' ', '_'); + JDiff.newFileName = filename + ".xml"; + JDiff.writeXML = false; + JDiff.compareAPIs = true; + } + continue; + } + if (options[i][0].toLowerCase().equals("-newapidir")) { + if (options[i].length < 2) { + err.msg("No directory specified after -newapidir option."); + } else { + JDiff.newDirectory = options[i][1]; + } + continue; + } + if (options[i][0].toLowerCase().equals("-usercommentsdir")) { + if (options[i].length < 2) { + err.msg("Android: No directory specified after -usercommentsdir option."); + } else { + HTMLReportGenerator.commentsDir = options[i][1]; + } + continue; + } + if (options[i][0].toLowerCase().equals("-d")) { + if (options[i].length < 2) { + err.msg("No directory specified after -d option."); + } else { + HTMLReportGenerator.outputDir = options[i][1]; + } + continue; + } + if (options[i][0].toLowerCase().equals("-javadocnew")) { + if (options[i].length < 2) { + err.msg("No location specified after -javadocnew option."); + } else { + HTMLReportGenerator.newDocPrefix = options[i][1]; + } + continue; + } + if (options[i][0].toLowerCase().equals("-javadocold")) { + if (options[i].length < 2) { + err.msg("No location specified after -javadocold option."); + } else { + HTMLReportGenerator.oldDocPrefix = options[i][1]; + } + continue; + } + if (options[i][0].toLowerCase().equals("-baseuri")) { + if (options[i].length < 2) { + err.msg("No base location specified after -baseURI option."); + } else { + RootDocToXML.baseURI = options[i][1]; + } + continue; + } + if (options[i][0].toLowerCase().equals("-excludeclass")) { + if (options[i].length < 2) { + err.msg("No level (public|protected|package|private) specified after -excludeclass option."); + } else { + String level = options[i][1]; + if (level.compareTo("public") != 0 && + level.compareTo("protected") != 0 && + level.compareTo("package") != 0 && + level.compareTo("private") != 0) { + err.msg("Level specified after -excludeclass option must be one of (public|protected|package|private)."); + } else { + RootDocToXML.classVisibilityLevel = level; + } + } + continue; + } + if (options[i][0].toLowerCase().equals("-excludemember")) { + if (options[i].length < 2) { + err.msg("No level (public|protected|package|private) specified after -excludemember option."); + } else { + String level = options[i][1]; + if (level.compareTo("public") != 0 && + level.compareTo("protected") != 0 && + level.compareTo("package") != 0 && + level.compareTo("private") != 0) { + err.msg("Level specified after -excludemember option must be one of (public|protected|package|private)."); + } else { + RootDocToXML.memberVisibilityLevel = level; + } + } + continue; + } + if (options[i][0].toLowerCase().equals("-firstsentence")) { + RootDocToXML.saveAllDocs = false; + continue; + } + if (options[i][0].toLowerCase().equals("-docchanges")) { + HTMLReportGenerator.reportDocChanges = true; + Diff.noDocDiffs = false; + continue; + } + if (options[i][0].toLowerCase().equals("-packagesonly")) { + RootDocToXML.packagesOnly = true; + continue; + } + if (options[i][0].toLowerCase().equals("-showallchanges")) { + Diff.showAllChanges = true; + continue; + } + if (options[i][0].toLowerCase().equals("-nosuggest")) { + if (options[i].length < 2) { + err.msg("No level (all|remove|add|change) specified after -nosuggest option."); + } else { + String level = options[i][1]; + if (level.compareTo("all") != 0 && + level.compareTo("remove") != 0 && + level.compareTo("add") != 0 && + level.compareTo("change") != 0) { + err.msg("Level specified after -nosuggest option must be one of (all|remove|add|change)."); + } else { + if (level.compareTo("removal") == 0) + HTMLReportGenerator.noCommentsOnRemovals = true; + else if (level.compareTo("add") == 0) + HTMLReportGenerator.noCommentsOnAdditions = true; + else if (level.compareTo("change") == 0) + HTMLReportGenerator.noCommentsOnChanges = true; + else if (level.compareTo("all") == 0) { + HTMLReportGenerator.noCommentsOnRemovals = true; + HTMLReportGenerator.noCommentsOnAdditions = true; + HTMLReportGenerator.noCommentsOnChanges = true; + } + } + } + continue; + } + if (options[i][0].toLowerCase().equals("-checkcomments")) { + APIHandler.checkIsSentence = true; + continue; + } + if (options[i][0].toLowerCase().equals("-retainnonprinting")) { + RootDocToXML.stripNonPrintables = false; + continue; + } + if (options[i][0].toLowerCase().equals("-excludetag")) { + if (options[i].length < 2) { + err.msg("No exclude tag specified after -excludetag option."); + } else { + RootDocToXML.excludeTag = options[i][1]; + RootDocToXML.excludeTag = RootDocToXML.excludeTag.trim(); + RootDocToXML.doExclude = true; + } + continue; + } + if (options[i][0].toLowerCase().equals("-stats")) { + HTMLReportGenerator.doStats = true; + continue; + } + if (options[i][0].toLowerCase().equals("-doctitle")) { + if (options[i].length < 2) { + err.msg("No HTML text specified after -doctitle option."); + } else { + HTMLReportGenerator.docTitle = options[i][1]; + } + continue; + } + if (options[i][0].toLowerCase().equals("-windowtitle")) { + if (options[i].length < 2) { + err.msg("No text specified after -windowtitle option."); + } else { + HTMLReportGenerator.windowTitle = options[i][1]; + } + continue; + } + if (options[i][0].toLowerCase().equals("-version")) { + System.out.println("JDiff version: " + JDiff.version); + System.exit(0); + } + if (options[i][0].toLowerCase().equals("-help")) { + usage(); + System.exit(0); + } + }//for + if (!JDiff.writeXML && !JDiff.compareAPIs) { + err.msg("First use the -apiname option to generate an XML file for one API."); + err.msg("Then use the -apiname option again to generate another XML file for a different version of the API."); + err.msg("Finally use the -oldapi option and -newapi option to generate a report about how the APIs differ."); + } + return err.noErrorsFound; + }// validOptions() + + /** Display the arguments for JDiff. */ + public static void usage() { + System.err.println("JDiff version: " + JDiff.version); + System.err.println(""); + System.err.println("Valid JDiff arguments:"); + System.err.println(""); + System.err.println(" -apiname <Name of a version>"); + System.err.println(" -oldapi <Name of a version>"); + System.err.println(" -newapi <Name of a version>"); + + System.err.println(" Optional Arguments"); + System.err.println(); + System.err.println(" -d <directory> Destination directory for output HTML files"); + System.err.println(" -oldapidir <directory> Location of the XML file for the old API"); + System.err.println(" -newapidir <directory> Location of the XML file for the new API"); + System.err.println(" -sourcepath <location of Java source files>"); + System.err.println(" -javadocnew <location of existing Javadoc files for the new API>"); + System.err.println(" -javadocold <location of existing Javadoc files for the old API>"); + System.err.println(" -usercommentsdir <directory> Path to dir containing the user_comments* file(s)"); + + System.err.println(" -baseURI <base> Use \"base\" as the base location of the various DTDs and Schemas used by JDiff"); + System.err.println(" -excludeclass [public|protected|package|private] Exclude classes which are not public, protected etc"); + System.err.println(" -excludemember [public|protected|package|private] Exclude members which are not public, protected etc"); + + System.err.println(" -firstsentence Save only the first sentence of each comment block with the API."); + System.err.println(" -docchanges Report changes in Javadoc comments between the APIs"); + System.err.println(" -nosuggest [all|remove|add|change] Do not add suggested comments to all, or the removed, added or chabged sections"); + System.err.println(" -checkcomments Check that comments are sentences"); + System.err.println(" -stripnonprinting Remove non-printable characters from comments."); + System.err.println(" -excludetag <tag> Define the Javadoc tag which implies exclusion"); + System.err.println(" -stats Generate statistical output"); + System.err.println(" -help (generates this output)"); + System.err.println(""); + System.err.println("For more help, see jdiff.html"); + } + + /** All the options passed on the command line. Logged to XML. */ + public static String cmdOptions = ""; + + /** Set to enable increased logging verbosity for debugging. */ + private static boolean trace = false; +} |