>")) {
name = name.substring(13);
}
return name;
}
/**
* Emit the XML header.
*/
public void emitXMLHeader() {
outputFile.println("");
outputFile.println("");
outputFile.println("");
outputFile.println("");
outputFile.println();
/* No need for this any longer, since doc block text is in an CDATA element
outputFile.println("");
outputFile.println("");
outputFile.println("");
*/
outputFile.println("");
outputFile.println();
}
/**
* Emit the XML footer.
*/
public void emitXMLFooter() {
outputFile.println();
outputFile.println("");
}
/**
* Determine if the program element is shown, according to the given
* level of visibility.
*
* @param ped The given program element.
* @param visLevel The desired visibility level; "public", "protected",
* "package" or "private". If null, only check for an exclude tag.
* @return boolean Set if this element is shown.
*/
public boolean shownElement(Doc doc, String visLevel) {
// If a doc block contains @exclude or a similar such tag,
// then don't display it.
if (doExclude && excludeTag != null && doc != null) {
String rct = doc.getRawCommentText();
if (rct != null && rct.indexOf(excludeTag) != -1) {
return false;
}
}
if (visLevel == null) {
return true;
}
ProgramElementDoc ped = null;
if (doc instanceof ProgramElementDoc) {
ped = (ProgramElementDoc)doc;
}
if (visLevel.compareTo("private") == 0)
return true;
// Show all that is not private
if (visLevel.compareTo("package") == 0)
return !ped.isPrivate();
// Show all that is not private or package
if (visLevel.compareTo("protected") == 0)
return !(ped.isPrivate() || ped.isPackagePrivate());
// Show all that is not private or package or protected,
// i.e. all that is public
if (visLevel.compareTo("public") == 0)
return ped.isPublic();
return false;
} //shownElement()
/**
* Strip out non-printing characters, replacing them with a character
* which will not change where the end of the first sentence is found.
* This character is the hash mark, '#'.
*/
public String stripNonPrintingChars(String s, Doc doc) {
if (!stripNonPrintables)
return s;
char[] sa = s.toCharArray();
for (int i = 0; i < sa.length; i++) {
char c = sa[i];
// TODO still have an issue with Unicode: 0xfc in java.lang.String.toUpperCase comments
// if (Character.isDefined(c))
if (Character.isLetterOrDigit(c))
continue;
// There must be a better way that is still platform independent!
if (c == ' ' ||
c == '.' ||
c == ',' ||
c == '\r' ||
c == '\t' ||
c == '\n' ||
c == '!' ||
c == '?' ||
c == ';' ||
c == ':' ||
c == '[' ||
c == ']' ||
c == '(' ||
c == ')' ||
c == '~' ||
c == '@' ||
c == '#' ||
c == '$' ||
c == '%' ||
c == '^' ||
c == '&' ||
c == '*' ||
c == '-' ||
c == '=' ||
c == '+' ||
c == '_' ||
c == '|' ||
c == '\\' ||
c == '/' ||
c == '\'' ||
c == '}' ||
c == '{' ||
c == '"' ||
c == '<' ||
c == '>' ||
c == '`'
)
continue;
/* Doesn't seem to return the expected values?
int val = Character.getNumericValue(c);
// if (s.indexOf("which is also a test for non-printable") != -1)
// System.out.println("** Char " + i + "[" + c + "], val =" + val); //DEBUG
// Ranges from http://www.unicode.org/unicode/reports/tr20/
// Should really replace 0x2028 and 0x2029 with
if (val == 0x0 ||
inRange(val, 0x2028, 0x2029) ||
inRange(val, 0x202A, 0x202E) ||
inRange(val, 0x206A, 0x206F) ||
inRange(val, 0xFFF9, 0xFFFC) ||
inRange(val, 0xE0000, 0xE007F)) {
if (trace) {
System.out.println("Warning: changed non-printing character " + sa[i] + " in " + doc.name());
}
sa[i] = '#';
}
*/
// Replace the non-printable character with a printable character
// which does not change the end of the first sentence
sa[i] = '#';
}
return new String(sa);
}
/** Return true if val is in the range [min|max], inclusive. */
public boolean inRange(int val, int min, int max) {
if (val < min)
return false;
if (val > max)
return false;
return true;
}
/**
* Add at least the first sentence from a doc block to the API. This is
* used by the report generator if no comment is provided.
* Need to make sure that HTML tags are not confused with XML tags.
* This could be done by stuffing the < character to another string
* or by handling HTML in the parser. This second option seems neater. Note that
* XML expects all element tags to have either a closing "/>" or a matching
* end element tag. Due to the difficulties of converting incorrect HTML
* to XHTML, the first option is used.
*/
public void addDocumentation(ProgramElementDoc ped, int indent) {
String rct = ((Doc)ped).getRawCommentText();
if (rct != null) {
rct = stripNonPrintingChars(rct, (Doc)ped);
rct = rct.trim();
if (rct.compareTo("") != 0 &&
rct.indexOf(Comments.placeHolderText) == -1 &&
rct.indexOf("InsertOtherCommentsHere") == -1) {
int idx = endOfFirstSentence(rct);
if (idx == 0)
return;
for (int i = 0; i < indent; i++) outputFile.print(" ");
outputFile.println("");
for (int i = 0; i < indent; i++) outputFile.print(" ");
String firstSentence = null;
if (idx == -1)
firstSentence = rct;
else
firstSentence = rct.substring(0, idx+1);
boolean checkForAts = false;
if (checkForAts && firstSentence.indexOf("@") != -1 &&
firstSentence.indexOf("@link") == -1) {
System.out.println("Warning: @ tag seen in comment: " +
firstSentence);
}
String firstSentenceNoTags = API.stuffHTMLTags(firstSentence);
outputFile.println(firstSentenceNoTags);
for (int i = 0; i < indent; i++) outputFile.print(" ");
outputFile.println("");
}
}
}
/**
* Add at least the first sentence from a doc block for a package to the API. This is
* used by the report generator if no comment is provided.
* The default source tree may not include the package.html files, so
* this may be unavailable in many cases.
* Need to make sure that HTML tags are not confused with XML tags.
* This could be done by stuffing the < character to another string
* or by handling HTML in the parser. This second option is neater. Note that
* XML expects all element tags to have either a closing "/>" or a matching
* end element tag. Due to the difficulties of converting incorrect HTML
* to XHTML, the first option is used.
*/
public void addPkgDocumentation(RootDoc root, PackageDoc pd, int indent) {
String rct = null;
String filename = pd.name();
try {
// See if the source path was specified as part of the
// options and prepend it if it was.
String srcLocation = null;
String[][] options = root.options();
for (int opt = 0; opt < options.length; opt++) {
if ((options[opt][0]).compareTo("-sourcepath") == 0) {
srcLocation = options[opt][1];
break;
}
}
filename = filename.replace('.', JDiff.DIR_SEP.charAt(0));
if (srcLocation != null) {
// Make a relative location absolute
if (srcLocation.startsWith("..")) {
String curDir = System.getProperty("user.dir");
while (srcLocation.startsWith("..")) {
srcLocation = srcLocation.substring(3);
int idx = curDir.lastIndexOf(JDiff.DIR_SEP);
curDir = curDir.substring(0, idx+1);
}
srcLocation = curDir + srcLocation;
}
filename = srcLocation + JDiff.DIR_SEP + filename;
}
// Try both ".htm" and ".html"
filename += JDiff.DIR_SEP + "package.htm";
File f2 = new File(filename);
if (!f2.exists()) {
filename += "l";
}
FileInputStream f = new FileInputStream(filename);
BufferedReader d = new BufferedReader(new InputStreamReader(f));
String str = d.readLine();
// Ignore everything except the lines between elements
boolean inBody = false;
while(str != null) {
if (!inBody) {
if (str.toLowerCase().trim().startsWith("");
for (int i = 0; i < indent; i++) outputFile.print(" ");
String firstSentence = null;
if (idx == -1)
firstSentence = rct;
else
firstSentence = rct.substring(0, idx+1);
String firstSentenceNoTags = API.stuffHTMLTags(firstSentence);
outputFile.println(firstSentenceNoTags);
for (int i = 0; i < indent; i++) outputFile.print(" ");
outputFile.println("");
}
}
}
/**
* Find the index of the end of the first sentence in the given text,
* when writing out to an XML file.
* This is an extended version of the algorithm used by the DocCheck
* Javadoc doclet. It checks for @tags too.
*
* @param text The text to be searched.
* @return The index of the end of the first sentence. If there is no
* end, return -1. If there is no useful text, return 0.
* If the whole doc block comment is wanted (default), return -1.
*/
public static int endOfFirstSentence(String text) {
return endOfFirstSentence(text, true);
}
/**
* Find the index of the end of the first sentence in the given text.
* This is an extended version of the algorithm used by the DocCheck
* Javadoc doclet. It checks for @tags too.
*
* @param text The text to be searched.
* @param writingToXML Set to true when writing out XML.
* @return The index of the end of the first sentence. If there is no
* end, return -1. If there is no useful text, return 0.
* If the whole doc block comment is wanted (default), return -1.
*/
public static int endOfFirstSentence(String text, boolean writingToXML) {
if (saveAllDocs && writingToXML)
return -1;
int textLen = text.length();
if (textLen == 0)
return 0;
int index = -1;
// Handle some special cases
int fromindex = 0;
int ellipsis = text.indexOf(". . ."); // Handles one instance of this
if (ellipsis != -1)
fromindex = ellipsis + 5;
// If the first non-whitespace character is an @, go beyond it
int i = 0;
while (i < textLen && text.charAt(i) == ' ') {
i++;
}
if (text.charAt(i) == '@' && fromindex < textLen-1)
fromindex = i + 1;
// Use the brute force approach.
index = minIndex(index, text.indexOf("? ", fromindex));
index = minIndex(index, text.indexOf("?\t", fromindex));
index = minIndex(index, text.indexOf("?\n", fromindex));
index = minIndex(index, text.indexOf("?\r", fromindex));
index = minIndex(index, text.indexOf("?\f", fromindex));
index = minIndex(index, text.indexOf("! ", fromindex));
index = minIndex(index, text.indexOf("!\t", fromindex));
index = minIndex(index, text.indexOf("!\n", fromindex));
index = minIndex(index, text.indexOf("!\r", fromindex));
index = minIndex(index, text.indexOf("!\f", fromindex));
index = minIndex(index, text.indexOf(". ", fromindex));
index = minIndex(index, text.indexOf(".\t", fromindex));
index = minIndex(index, text.indexOf(".\n", fromindex));
index = minIndex(index, text.indexOf(".\r", fromindex));
index = minIndex(index, text.indexOf(".\f", fromindex));
index = minIndex(index, text.indexOf("@param", fromindex));
index = minIndex(index, text.indexOf("@return", fromindex));
index = minIndex(index, text.indexOf("@throw", fromindex));
index = minIndex(index, text.indexOf("@serial", fromindex));
index = minIndex(index, text.indexOf("@exception", fromindex));
index = minIndex(index, text.indexOf("@deprecate", fromindex));
index = minIndex(index, text.indexOf("@author", fromindex));
index = minIndex(index, text.indexOf("@since", fromindex));
index = minIndex(index, text.indexOf("@see", fromindex));
index = minIndex(index, text.indexOf("@version", fromindex));
if (doExclude && excludeTag != null)
index = minIndex(index, text.indexOf(excludeTag));
index = minIndex(index, text.indexOf("@vtexclude", fromindex));
index = minIndex(index, text.indexOf("@vtinclude", fromindex));
index = minIndex(index, text.indexOf("", 2)); // Not at start
index = minIndex(index, text.indexOf("
", 2)); // Not at start
index = minIndex(index, text.indexOf("
-1, and return -1
* only if both indexes = -1.
* @param i an int index
* @param j an int index
* @return an int equal to the minimum index > -1, or -1
*/
public static int minIndex(int i, int j) {
if (i == -1) return j;
if (j == -1) return i;
return Math.min(i,j);
}
/**
* The name of the file where the XML representing the API will be
* stored.
*/
public static String outputFileName = null;
/**
* The identifier of the API being written out in XML, e.g.
* "SuperProduct 1.3".
*/
public static String apiIdentifier = null;
/**
* The file where the XML representing the API will be stored.
*/
private static PrintWriter outputFile = null;
/**
* The name of the directory where the XML representing the API will be
* stored.
*/
public static String outputDirectory = null;
/**
* Do not display a class with a lower level of visibility than this.
* Default is to display all public and protected classes.
*/
public static String classVisibilityLevel = "protected";
/**
* Do not display a member with a lower level of visibility than this.
* Default is to display all public and protected members
* (constructors, methods, fields).
*/
public static String memberVisibilityLevel = "protected";
/**
* If set, then save the entire contents of a doc block comment in the
* API file. If not set, then just save the first sentence. Default is
* that this is set.
*/
public static boolean saveAllDocs = true;
/**
* If set, exclude program elements marked with whatever the exclude tag
* is specified as, e.g. "@exclude".
*/
public static boolean doExclude = false;
/**
* Exclude program elements marked with this String, e.g. "@exclude".
*/
public static String excludeTag = null;
/**
* The base URI for locating necessary DTDs and Schemas. By default, this
* is "http://www.w3.org". A typical value to use local copies of DTD files
* might be "file:///C:/jdiff/lib"
*/
public static String baseURI = "http://www.w3.org";
/**
* If set, then strip out non-printing characters from documentation.
* Default is that this is set.
*/
static boolean stripNonPrintables = true;
/**
* If set, then add the information about the source file and line number
* which is available in J2SE1.4. Default is that this is not set.
*/
static boolean addSrcInfo = false;
/**
* If set, scan classes with no packages.
* If the source is a jar file this may duplicates classes, so
* disable it using the -packagesonly option. Default is that this is
* not set.
*/
static boolean packagesOnly = false;
/** Set to enable increased logging verbosity for debugging. */
private static boolean trace = false;
} //RootDocToXML