RootDocToXMLpublic class RootDocToXML extends Object Converts a Javadoc RootDoc object into a representation in an
XML file.
See the file LICENSE.txt for copyright details. |
Fields Summary |
---|
public static String | outputFileNameThe name of the file where the XML representing the API will be
stored. | public static String | apiIdentifierThe identifier of the API being written out in XML, e.g.
"SuperProduct 1.3". | private static PrintWriter | outputFileThe file where the XML representing the API will be stored. | public static String | outputDirectoryThe name of the directory where the XML representing the API will be
stored. | public static String | classVisibilityLevelDo not display a class with a lower level of visibility than this.
Default is to display all public and protected classes. | public static String | memberVisibilityLevelDo 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 boolean | saveAllDocsIf 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 | doExcludeIf set, exclude program elements marked with whatever the exclude tag
is specified as, e.g. "@exclude". | public static String | excludeTagExclude program elements marked with this String, e.g. "@exclude". | public static String | baseURIThe 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" | static boolean | stripNonPrintablesIf set, then strip out non-printing characters from documentation.
Default is that this is set. | static boolean | addSrcInfoIf 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 | packagesOnlyIf 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. | private static boolean | traceSet to enable increased logging verbosity for debugging. |
Constructors Summary |
---|
public RootDocToXML()Default constructor.
|
Methods Summary |
---|
public void | addCommonModifiers(com.sun.javadoc.ProgramElementDoc ped, int indent)Add qualifiers for the program element as attributes.
addSourcePosition(ped, indent);
// Static and final and visibility on one line
for (int i = 0; i < indent; i++) outputFile.print(" ");
outputFile.print("static=\"" + ped.isStatic() + "\"");
outputFile.print(" final=\"" + ped.isFinal() + "\"");
// Visibility
String visibility = null;
if (ped.isPublic())
visibility = "public";
else if (ped.isProtected())
visibility = "protected";
else if (ped.isPackagePrivate())
visibility = "package";
else if (ped.isPrivate())
visibility = "private";
outputFile.println(" visibility=\"" + visibility + "\"");
// Deprecation on its own line
for (int i = 0; i < indent; i++) outputFile.print(" ");
boolean isDeprecated = false;
Tag[] ta = ((Doc)ped).tags("deprecated");
if (ta.length != 0) {
isDeprecated = true;
}
if (ta.length > 1) {
System.out.println("JDiff: warning: multiple @deprecated tags found in comments for " + ped.name() + ". Using the first one only.");
System.out.println("Text is: " + ((Doc)ped).getRawCommentText());
}
if (isDeprecated) {
String text = ta[0].text(); // Use only one @deprecated tag
if (text != null && text.compareTo("") != 0) {
int idx = endOfFirstSentence(text);
if (idx == 0) {
// No useful comment
outputFile.print("deprecated=\"deprecated, no comment\"");
} else {
String fs = null;
if (idx == -1)
fs = text;
else
fs = text.substring(0, idx+1);
String st = API.hideHTMLTags(fs);
outputFile.print("deprecated=\"" + st + "\"");
}
} else {
outputFile.print("deprecated=\"deprecated, no comment\"");
}
} else {
outputFile.print("deprecated=\"not deprecated\"");
}
| public void | addDocumentation(com.sun.javadoc.ProgramElementDoc ped, int indent)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.
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("<doc>");
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("</doc>");
}
}
| public void | addPkgDocumentation(com.sun.javadoc.RootDoc root, com.sun.javadoc.PackageDoc pd, int indent)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.
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 <body> elements
boolean inBody = false;
while(str != null) {
if (!inBody) {
if (str.toLowerCase().trim().startsWith("<body")) {
inBody = true;
}
str = d.readLine(); // Get the next line
continue; // Ignore the line
} else {
if (str.toLowerCase().trim().startsWith("</body")) {
inBody = false;
continue; // Ignore the line
}
}
if (rct == null)
rct = str + "\n";
else
rct += str + "\n";
str = d.readLine();
}
} catch(java.io.FileNotFoundException e) {
// If it doesn't exist, that's fine
if (trace)
System.out.println("No package level documentation file at '" + filename + "'");
} catch(java.io.IOException e) {
System.out.println("Error reading file \"" + filename + "\": " + e.getMessage());
System.exit(5);
}
if (rct != null) {
rct = stripNonPrintingChars(rct, (Doc)pd);
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("<doc>");
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("</doc>");
}
}
| public void | addSourcePosition(com.sun.javadoc.ProgramElementDoc ped, int indent)Insert the source code details, if available.
if (!addSrcInfo)
return;
if (JDiff.javaVersion.startsWith("1.1") ||
JDiff.javaVersion.startsWith("1.2") ||
JDiff.javaVersion.startsWith("1.3")) {
return; // position() only appeared in J2SE1.4
}
try {
// Could cache the method for improved performance
Class c = ProgramElementDoc.class;
Method m = c.getMethod("position", (Class[]) null);
Object sp = m.invoke(ped, (Object[]) null);
if (sp != null) {
for (int i = 0; i < indent; i++) outputFile.print(" ");
outputFile.println("src=\"" + sp + "\"");
}
} catch (NoSuchMethodException e2) {
System.err.println("Error: method \"position\" not found");
e2.printStackTrace();
} catch (IllegalAccessException e4) {
System.err.println("Error: class not permitted to be instantiated");
e4.printStackTrace();
} catch (InvocationTargetException e5) {
System.err.println("Error: method \"position\" could not be invoked");
e5.printStackTrace();
} catch (Exception e6) {
System.err.println("Error: ");
e6.printStackTrace();
}
| private java.lang.String | buildEmittableTypeString(com.sun.javadoc.Type type)Build the emittable type name. The type may be an array and/or
a generic type.
if (type == null) {
return null;
}
// type.toString() returns the fully qualified name of the type
// including the dimension and the parameters we just need to
// escape the generic parameters brackets so that the XML
// generated is correct
String name = type.toString().replaceAll("<", "<").replaceAll(">", ">");
if (name.startsWith("<<ambiguous>>")) {
name = name.substring(13);
}
return name;
| public void | emitType(com.sun.javadoc.Type type)Emit the type name. Removed any prefixed warnings about ambiguity.
The type maybe an array.
String name = buildEmittableTypeString(type);
if (name == null)
return;
outputFile.print(name);
| public void | emitXMLFooter()Emit the XML footer.
outputFile.println();
outputFile.println("</api>");
| public void | emitXMLHeader()Emit the XML header.
outputFile.println("<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"no\"?>");
outputFile.println("<!-- Generated by the JDiff Javadoc doclet -->");
outputFile.println("<!-- (" + JDiff.jDiffLocation + ") -->");
outputFile.println("<!-- on " + new Date() + " -->");
outputFile.println();
/* No need for this any longer, since doc block text is in an CDATA element
outputFile.println("<!-- XML Schema is used, but XHTML transitional DTD is needed for nbsp -->");
outputFile.println("<!-- entity definitions etc.-->");
outputFile.println("<!DOCTYPE api");
outputFile.println(" PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"");
outputFile.println(" \"" + baseURI + "/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
*/
outputFile.println("<api");
outputFile.println(" xmlns:xsi='" + baseURI + "/2001/XMLSchema-instance'");
outputFile.println(" xsi:noNamespaceSchemaLocation='api.xsd'");
outputFile.println(" name=\"" + apiIdentifier + "\"");
outputFile.println(" jdversion=\"" + JDiff.version + "\">");
outputFile.println();
| public static int | endOfFirstSentence(java.lang.String text)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.
return endOfFirstSentence(text, true);
| public static int | endOfFirstSentence(java.lang.String text, boolean writingToXML)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.
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("<p>", 2)); // Not at start
index = minIndex(index, text.indexOf("<P>", 2)); // Not at start
index = minIndex(index, text.indexOf("<blockquote", 2)); // Not at start
index = minIndex(index, text.indexOf("<pre", fromindex)); // May contain anything!
// Avoid the char at the start of a tag in some cases
if (index != -1 &&
(text.charAt(index) == '@" || text.charAt(index) == '<")) {
if (index != 0)
index--;
}
/* Not used for jdiff, since tags are explicitly checked for above.
// Look for a sentence terminated by an HTML tag.
index = minIndex(index, text.indexOf(".<", fromindex));
if (index == -1) {
// If period-whitespace etc was not found, check to see if
// last character is a period,
int endIndex = text.length()-1;
if (text.charAt(endIndex) == '.' ||
text.charAt(endIndex) == '?' ||
text.charAt(endIndex) == '!')
index = endIndex;
}
*/
return index;
| public boolean | inRange(int val, int min, int max)Return true if val is in the range [min|max], inclusive.
if (val < min)
return false;
if (val > max)
return false;
return true;
| public void | logOptions()Write the options which were used to generate this XML file
out as XML comments.
outputFile.print("<!-- ");
outputFile.print(" Command line arguments = " + Options.cmdOptions);
outputFile.println(" -->");
| public static int | minIndex(int i, int j)Return the minimum of two indexes if > -1, and return -1
only if both indexes = -1.
if (i == -1) return j;
if (j == -1) return i;
return Math.min(i,j);
| public void | processClasses(com.sun.javadoc.ClassDoc[] cd, java.lang.String pkgName)Process classes and interfaces.
if (cd.length == 0)
return;
if (trace) System.out.println("PROCESSING CLASSES, number=" + cd.length);
for (int i = 0; i < cd.length; i++) {
String className = cd[i].name();
if (trace) System.out.println("PROCESSING CLASS/IFC: " + className);
// Only save the shown elements
if (!shownElement(cd[i], classVisibilityLevel))
continue;
boolean isInterface = false;
if (cd[i].isInterface())
isInterface = true;
if (isInterface) {
outputFile.println(" <!-- start interface " + pkgName + "." + className + " -->");
outputFile.print(" <interface name=\"" + className + "\"");
} else {
outputFile.println(" <!-- start class " + pkgName + "." + className + " -->");
outputFile.print(" <class name=\"" + className + "\"");
}
// Add attributes to the class element
Type parent = cd[i].superclassType();
if (parent != null)
outputFile.println(" extends=\"" + buildEmittableTypeString(parent) + "\"");
outputFile.println(" abstract=\"" + cd[i].isAbstract() + "\"");
addCommonModifiers(cd[i], 4);
outputFile.println(">");
// Process class members. (Treat inner classes as members.)
processInterfaces(cd[i].interfaceTypes());
processConstructors(cd[i].constructors());
processMethods(cd[i], cd[i].methods());
processFields(cd[i].fields());
addDocumentation(cd[i], 4);
if (isInterface) {
outputFile.println(" </interface>");
outputFile.println(" <!-- end interface " + pkgName + "." + className + " -->");
} else {
outputFile.println(" </class>");
outputFile.println(" <!-- end class " + pkgName + "." + className + " -->");
}
// Inner classes have already been added.
/*
ClassDoc[] ic = cd[i].innerClasses();
for (int k = 0; k < ic.length; k++) {
System.out.println("Inner class " + k + ", name = " + ic[k].name());
}
*/
}//for
| public void | processConstructors(com.sun.javadoc.ConstructorDoc[] ct)Process the constructors in the class.
if (trace) System.out.println("PROCESSING CONSTRUCTORS, number=" + ct.length);
for (int i = 0; i < ct.length; i++) {
String ctorName = ct[i].name();
if (trace) System.out.println("PROCESSING CONSTRUCTOR: " + ctorName);
// Only save the shown elements
if (!shownElement(ct[i], memberVisibilityLevel))
continue;
outputFile.print(" <constructor name=\"" + ctorName + "\"");
Parameter[] params = ct[i].parameters();
boolean first = true;
if (params.length != 0) {
outputFile.print(" type=\"");
for (int j = 0; j < params.length; j++) {
if (!first)
outputFile.print(", ");
emitType(params[j].type());
first = false;
}
outputFile.println("\"");
} else
outputFile.println();
addCommonModifiers(ct[i], 6);
outputFile.println(">");
// Generate the exception elements if any exceptions are thrown
processExceptions(ct[i].thrownExceptions());
addDocumentation(ct[i], 6);
outputFile.println(" </constructor>");
}//for
| public void | processExceptions(com.sun.javadoc.ClassDoc[] cd)Process all exceptions thrown by a constructor or method.
if (trace) System.out.println("PROCESSING EXCEPTIONS, number=" + cd.length);
for (int i = 0; i < cd.length; i++) {
String exceptionName = cd[i].name();
if (trace) System.out.println("PROCESSING EXCEPTION: " + exceptionName);
outputFile.print(" <exception name=\"" + exceptionName + "\" type=\"");
emitType(cd[i]);
outputFile.println("\"/>");
}//for
| public void | processFields(com.sun.javadoc.FieldDoc[] fd)Process the fields in the class.
if (trace) System.out.println("PROCESSING FIELDS, number=" + fd.length);
for (int i = 0; i < fd.length; i++) {
String fieldName = fd[i].name();
if (trace) System.out.println("PROCESSING FIELD: " + fieldName);
// Only save the shown elements
if (!shownElement(fd[i], memberVisibilityLevel))
continue;
outputFile.print(" <field name=\"" + fieldName + "\"");
outputFile.print(" type=\"");
emitType(fd[i].type());
outputFile.println("\"");
outputFile.print(" transient=\"" + fd[i].isTransient() + "\"");
outputFile.println(" volatile=\"" + fd[i].isVolatile() + "\"");
/* JDK 1.4 and later */
/*
String value = fd[i].constantValueExpression();
if (value != null)
outputFile.println(" value=\"" + value + "\"");
*/
addCommonModifiers(fd[i], 6);
outputFile.println(">");
addDocumentation(fd[i], 6);
outputFile.println(" </field>");
}//for
| public void | processInterfaces(com.sun.javadoc.Type[] ifaces)Process the interfaces implemented by the class.
if (trace) System.out.println("PROCESSING INTERFACES, number=" + ifaces.length);
for (int i = 0; i < ifaces.length; i++) {
String ifaceName = buildEmittableTypeString(ifaces[i]);
if (trace) System.out.println("PROCESSING INTERFACE: " + ifaceName);
outputFile.println(" <implements name=\"" + ifaceName + "\"/>");
}//for
| public void | processMethods(com.sun.javadoc.ClassDoc cd, com.sun.javadoc.MethodDoc[] md)Process the methods in the class.
if (trace) System.out.println("PROCESSING " +cd.name()+" METHODS, number = " + md.length);
for (int i = 0; i < md.length; i++) {
String methodName = md[i].name();
if (trace) System.out.println("PROCESSING METHOD: " + methodName);
// Skip <init> and <clinit>
if (methodName.startsWith("<"))
continue;
// Only save the shown elements
if (!shownElement(md[i], memberVisibilityLevel))
continue;
outputFile.print(" <method name=\"" + methodName + "\"");
com.sun.javadoc.Type retType = md[i].returnType();
if (retType.qualifiedTypeName().compareTo("void") == 0) {
// Don't add a return attribute if the return type is void
outputFile.println();
} else {
outputFile.print(" return=\"");
emitType(retType);
outputFile.println("\"");
}
outputFile.print(" abstract=\"" + md[i].isAbstract() + "\"");
outputFile.print(" native=\"" + md[i].isNative() + "\"");
outputFile.println(" synchronized=\"" + md[i].isSynchronized() + "\"");
addCommonModifiers(md[i], 6);
outputFile.println(">");
// Generate the parameter elements, if any
Parameter[] params = md[i].parameters();
for (int j = 0; j < params.length; j++) {
outputFile.print(" <param name=\"" + params[j].name() + "\"");
outputFile.print(" type=\"");
emitType(params[j].type());
outputFile.println("\"/>");
}
// Generate the exception elements if any exceptions are thrown
processExceptions(md[i].thrownExceptions());
addDocumentation(md[i], 6);
outputFile.println(" </method>");
}//for
| public void | processPackages(com.sun.javadoc.RootDoc root)Process each package and the classes/interfaces within it.
PackageDoc[] specified_pd = root.specifiedPackages();
Map pdl = new TreeMap();
for (int i = 0; specified_pd != null && i < specified_pd.length; i++) {
pdl.put(specified_pd[i].name(), specified_pd[i]);
}
// Classes may be specified separately, so merge their packages into the
// list of specified packages.
ClassDoc[] cd = root.specifiedClasses();
// This is lists of the specific classes to document
Map classesToUse = new HashMap();
for (int i = 0; cd != null && i < cd.length; i++) {
PackageDoc cpd = cd[i].containingPackage();
if (cpd == null && !packagesOnly) {
// If the RootDoc object has been created from a jar file
// this duplicates classes, so we have to be able to disable it.
// TODO this is still null?
cpd = root.packageNamed("anonymous");
}
String pkgName = cpd.name();
String className = cd[i].name();
if (trace) System.out.println("Found package " + pkgName + " for class " + className);
if (!pdl.containsKey(pkgName)) {
if (trace) System.out.println("Adding new package " + pkgName);
pdl.put(pkgName, cpd);
}
// Keep track of the specific classes to be used for this package
List classes;
if (classesToUse.containsKey(pkgName)) {
classes = (ArrayList) classesToUse.get(pkgName);
} else {
classes = new ArrayList();
}
classes.add(cd[i]);
classesToUse.put(pkgName, classes);
}
PackageDoc[] pd = (PackageDoc[]) pdl.values().toArray(new PackageDoc[0]);
for (int i = 0; pd != null && i < pd.length; i++) {
String pkgName = pd[i].name();
// Check for an exclude tag in the package doc block, but not
// in the package.htm[l] file.
if (!shownElement(pd[i], null))
continue;
if (trace) System.out.println("PROCESSING PACKAGE: " + pkgName);
outputFile.println("<package name=\"" + pkgName + "\">");
int tagCount = pd[i].tags().length;
if (trace) System.out.println("#tags: " + tagCount);
List classList;
if (classesToUse.containsKey(pkgName)) {
// Use only the specified classes in the package
System.out.println("Using the specified classes");
classList = (ArrayList) classesToUse.get(pkgName);
} else {
// Use all classes in the package
classList = new LinkedList(Arrays.asList(pd[i].allClasses()));
}
Collections.sort(classList);
ClassDoc[] classes = new ClassDoc[classList.size()];
classes = (ClassDoc[])classList.toArray(classes);
processClasses(classes, pkgName);
addPkgDocumentation(root, pd[i], 2);
outputFile.println("</package>");
}
| public boolean | shownElement(com.sun.javadoc.Doc doc, java.lang.String visLevel)Determine if the program element is shown, according to the given
level of visibility.
// 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;
| public java.lang.String | stripNonPrintingChars(java.lang.String s, com.sun.javadoc.Doc doc)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, '#'.
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 <br/>
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);
| public static boolean | writeXML(com.sun.javadoc.RootDoc root)Write the XML representation of the API to a file.
String tempFileName = outputFileName;
if (outputDirectory != null) {
tempFileName = outputDirectory;
if (!tempFileName.endsWith(JDiff.DIR_SEP))
tempFileName += JDiff.DIR_SEP;
tempFileName += outputFileName;
}
try {
FileOutputStream fos = new FileOutputStream(tempFileName);
outputFile = new PrintWriter(fos);
System.out.println("JDiff: writing the API to file '" + tempFileName + "'...");
if (root.specifiedPackages().length != 0 || root.specifiedClasses().length != 0) {
RootDocToXML apiWriter = new RootDocToXML();
apiWriter.emitXMLHeader();
apiWriter.logOptions();
apiWriter.processPackages(root);
apiWriter.emitXMLFooter();
}
outputFile.close();
} catch(IOException e) {
System.out.println("IO Error while attempting to create " + tempFileName);
System.out.println("Error: " + e.getMessage());
System.exit(1);
}
// If validation is desired, write out the appropriate api.xsd file
// in the same directory as the XML file.
if (XMLToAPI.validateXML) {
writeXSD();
}
return true;
| public static void | writeXSD()Write the XML Schema file used for validation.
String xsdFileName = outputFileName;
if (outputDirectory == null) {
int idx = xsdFileName.lastIndexOf('\\");
int idx2 = xsdFileName.lastIndexOf('/");
if (idx == -1 && idx2 == -1) {
xsdFileName = "";
} else if (idx == -1 && idx2 != -1) {
xsdFileName = xsdFileName.substring(0, idx2);
} else if (idx != -1 && idx2 == -1) {
xsdFileName = xsdFileName.substring(0, idx);
} else if (idx != -1 && idx2 != -1) {
int max = idx2 > idx ? idx2 : idx;
xsdFileName = xsdFileName.substring(0, max);
}
} else {
xsdFileName = outputDirectory;
if (!xsdFileName.endsWith(JDiff.DIR_SEP))
xsdFileName += JDiff.DIR_SEP;
}
xsdFileName += "api.xsd";
try {
FileOutputStream fos = new FileOutputStream(xsdFileName);
PrintWriter xsdFile = new PrintWriter(fos);
// The contents of the api.xsd file
xsdFile.println("<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"no\"?>");
xsdFile.println("<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">");
xsdFile.println("");
xsdFile.println("<xsd:annotation>");
xsdFile.println(" <xsd:documentation>");
xsdFile.println(" Schema for JDiff API representation.");
xsdFile.println(" </xsd:documentation>");
xsdFile.println("</xsd:annotation>");
xsdFile.println();
xsdFile.println("<xsd:element name=\"api\" type=\"apiType\"/>");
xsdFile.println("");
xsdFile.println("<xsd:complexType name=\"apiType\">");
xsdFile.println(" <xsd:sequence>");
xsdFile.println(" <xsd:element name=\"package\" type=\"packageType\" minOccurs='1' maxOccurs='unbounded'/>");
xsdFile.println(" </xsd:sequence>");
xsdFile.println(" <xsd:attribute name=\"name\" type=\"xsd:string\"/>");
xsdFile.println(" <xsd:attribute name=\"jdversion\" type=\"xsd:string\"/>");
xsdFile.println("</xsd:complexType>");
xsdFile.println();
xsdFile.println("<xsd:complexType name=\"packageType\">");
xsdFile.println(" <xsd:sequence>");
xsdFile.println(" <xsd:choice maxOccurs='unbounded'>");
xsdFile.println(" <xsd:element name=\"class\" type=\"classType\"/>");
xsdFile.println(" <xsd:element name=\"interface\" type=\"classType\"/>");
xsdFile.println(" </xsd:choice>");
xsdFile.println(" <xsd:element name=\"doc\" type=\"xsd:string\" minOccurs='0' maxOccurs='1'/>");
xsdFile.println(" </xsd:sequence>");
xsdFile.println(" <xsd:attribute name=\"name\" type=\"xsd:string\"/>");
xsdFile.println("</xsd:complexType>");
xsdFile.println();
xsdFile.println("<xsd:complexType name=\"classType\">");
xsdFile.println(" <xsd:sequence>");
xsdFile.println(" <xsd:element name=\"implements\" type=\"interfaceTypeName\" minOccurs='0' maxOccurs='unbounded'/>");
xsdFile.println(" <xsd:element name=\"constructor\" type=\"constructorType\" minOccurs='0' maxOccurs='unbounded'/>");
xsdFile.println(" <xsd:element name=\"method\" type=\"methodType\" minOccurs='0' maxOccurs='unbounded'/>");
xsdFile.println(" <xsd:element name=\"field\" type=\"fieldType\" minOccurs='0' maxOccurs='unbounded'/>");
xsdFile.println(" <xsd:element name=\"doc\" type=\"xsd:string\" minOccurs='0' maxOccurs='1'/>");
xsdFile.println(" </xsd:sequence>");
xsdFile.println(" <xsd:attribute name=\"name\" type=\"xsd:string\"/>");
xsdFile.println(" <xsd:attribute name=\"extends\" type=\"xsd:string\" use='optional'/>");
xsdFile.println(" <xsd:attribute name=\"abstract\" type=\"xsd:boolean\"/>");
xsdFile.println(" <xsd:attribute name=\"src\" type=\"xsd:string\" use='optional'/>");
xsdFile.println(" <xsd:attribute name=\"static\" type=\"xsd:boolean\"/>");
xsdFile.println(" <xsd:attribute name=\"final\" type=\"xsd:boolean\"/>");
xsdFile.println(" <xsd:attribute name=\"deprecated\" type=\"xsd:string\"/>");
xsdFile.println(" <xsd:attribute name=\"visibility\" type=\"xsd:string\"/>");
xsdFile.println("</xsd:complexType>");
xsdFile.println();
xsdFile.println("<xsd:complexType name=\"interfaceTypeName\">");
xsdFile.println(" <xsd:attribute name=\"name\" type=\"xsd:string\"/>");
xsdFile.println("</xsd:complexType>");
xsdFile.println();
xsdFile.println("<xsd:complexType name=\"constructorType\">");
xsdFile.println(" <xsd:sequence>");
xsdFile.println(" <xsd:element name=\"exception\" type=\"exceptionType\" minOccurs='0' maxOccurs='unbounded'/>");
xsdFile.println(" <xsd:element name=\"doc\" type=\"xsd:string\" minOccurs='0' maxOccurs='1'/>");
xsdFile.println(" </xsd:sequence>");
xsdFile.println(" <xsd:attribute name=\"name\" type=\"xsd:string\"/>");
xsdFile.println(" <xsd:attribute name=\"type\" type=\"xsd:string\" use='optional'/>");
xsdFile.println(" <xsd:attribute name=\"src\" type=\"xsd:string\" use='optional'/>");
xsdFile.println(" <xsd:attribute name=\"static\" type=\"xsd:boolean\"/>");
xsdFile.println(" <xsd:attribute name=\"final\" type=\"xsd:boolean\"/>");
xsdFile.println(" <xsd:attribute name=\"deprecated\" type=\"xsd:string\"/>");
xsdFile.println(" <xsd:attribute name=\"visibility\" type=\"xsd:string\"/>");
xsdFile.println("</xsd:complexType>");
xsdFile.println();
xsdFile.println("<xsd:complexType name=\"paramsType\">");
xsdFile.println(" <xsd:attribute name=\"name\" type=\"xsd:string\"/>");
xsdFile.println(" <xsd:attribute name=\"type\" type=\"xsd:string\"/>");
xsdFile.println("</xsd:complexType>");
xsdFile.println();
xsdFile.println("<xsd:complexType name=\"exceptionType\">");
xsdFile.println(" <xsd:attribute name=\"name\" type=\"xsd:string\"/>");
xsdFile.println(" <xsd:attribute name=\"type\" type=\"xsd:string\"/>");
xsdFile.println("</xsd:complexType>");
xsdFile.println();
xsdFile.println("<xsd:complexType name=\"methodType\">");
xsdFile.println(" <xsd:sequence>");
xsdFile.println(" <xsd:element name=\"param\" type=\"paramsType\" minOccurs='0' maxOccurs='unbounded'/>");
xsdFile.println(" <xsd:element name=\"exception\" type=\"exceptionType\" minOccurs='0' maxOccurs='unbounded'/>");
xsdFile.println(" <xsd:element name=\"doc\" type=\"xsd:string\" minOccurs='0' maxOccurs='1'/>");
xsdFile.println(" </xsd:sequence>");
xsdFile.println(" <xsd:attribute name=\"name\" type=\"xsd:string\"/>");
xsdFile.println(" <xsd:attribute name=\"return\" type=\"xsd:string\" use='optional'/>");
xsdFile.println(" <xsd:attribute name=\"abstract\" type=\"xsd:boolean\"/>");
xsdFile.println(" <xsd:attribute name=\"native\" type=\"xsd:boolean\"/>");
xsdFile.println(" <xsd:attribute name=\"synchronized\" type=\"xsd:boolean\"/>");
xsdFile.println(" <xsd:attribute name=\"src\" type=\"xsd:string\" use='optional'/>");
xsdFile.println(" <xsd:attribute name=\"static\" type=\"xsd:boolean\"/>");
xsdFile.println(" <xsd:attribute name=\"final\" type=\"xsd:boolean\"/>");
xsdFile.println(" <xsd:attribute name=\"deprecated\" type=\"xsd:string\"/>");
xsdFile.println(" <xsd:attribute name=\"visibility\" type=\"xsd:string\"/>");
xsdFile.println("</xsd:complexType>");
xsdFile.println();
xsdFile.println("<xsd:complexType name=\"fieldType\">");
xsdFile.println(" <xsd:sequence>");
xsdFile.println(" <xsd:element name=\"doc\" type=\"xsd:string\" minOccurs='0' maxOccurs='1'/>");
xsdFile.println(" </xsd:sequence>");
xsdFile.println(" <xsd:attribute name=\"name\" type=\"xsd:string\"/>");
xsdFile.println(" <xsd:attribute name=\"type\" type=\"xsd:string\"/>");
xsdFile.println(" <xsd:attribute name=\"transient\" type=\"xsd:boolean\"/>");
xsdFile.println(" <xsd:attribute name=\"volatile\" type=\"xsd:boolean\"/>");
xsdFile.println(" <xsd:attribute name=\"value\" type=\"xsd:string\" use='optional'/>");
xsdFile.println(" <xsd:attribute name=\"src\" type=\"xsd:string\" use='optional'/>");
xsdFile.println(" <xsd:attribute name=\"static\" type=\"xsd:boolean\"/>");
xsdFile.println(" <xsd:attribute name=\"final\" type=\"xsd:boolean\"/>");
xsdFile.println(" <xsd:attribute name=\"deprecated\" type=\"xsd:string\"/>");
xsdFile.println(" <xsd:attribute name=\"visibility\" type=\"xsd:string\"/>");
xsdFile.println("</xsd:complexType>");
xsdFile.println();
xsdFile.println("</xsd:schema>");
xsdFile.close();
} catch(IOException e) {
System.out.println("IO Error while attempting to create " + xsdFileName);
System.out.println("Error: " + e.getMessage());
System.exit(1);
}
|
|