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;
|
}
|