Here are the basic steps you need to follow to create and useyour own doclet:
If you run javadoc without the-doclet command-lineoption, it will default to the standard doclet to produceHTML-format API documentation.
Package com.sun.javadoc consists of interfaces that define thedoclet API. Thelib/tools.jar file in the Java 2 SDKcontains these interfaces and also a private package with classesthat implement the interfaces. Thetools.jar file alsocontains the classes implementing the standard doclet.
importcom.sun.javadoc.*;public class ListClass { public static boolean start(RootDoc root) {ClassDoc[] classes = root.classes(); for (int i = 0; i < classes.length; ++i) { System.out.println(classes[i]); } return true; }}As you might be able to guess by looking at the code, this doclettakes the classes upon which Javadoc is operating and prints theirnames to standard out.
This first thing to notice about the doclet is that it importsthe com.sun.javadoc package in order to use the doclet APIs. Aswith all doclets, the entry point is thepublic static boolean start method. Thestart method takes a RootDoc as a parameter. Thisparameter carries information about any options specified on thecommand line when javadoc is run, and also about the classes andpackages upon which javadoc is operating.
RootDoc defines aclasses method that returns aClassDoc array whose elements represent the classes that Javadocparses. Thefor loop then prints out the names of eachclass in the array. (Passing a ClassDoc toprintln resultsin the printing of the name of the class that the ClassDocrepresents.)
To run this doclet, you first have to compile it. You cancompile it with the javac compiler. The doclet API classfiles arein the filelib/tools.jar in the Java 2 SDK which javacdoes not automatically load. You therefore need to includetools.jar on the compiler's classpath, as in thisexample:
javac -classpath C:\jdk1.3\lib\tools.jar ListClass.javaTo run the ListClass doclet, you point to the compiled doclet withJavadoc's-doclet and-docletpath tags. Forexample, to run the doclet on a file calledMyClass.java,you could use this command, assumingListClass.class is inthe current directory:
% javadoc -doclet ListClass -docletpath . MyClass.javaThe output will be the string "MyClass". Note that thiscommand does not requiretools.jar to be on the classpath, as the Javdoc tool automatically loads it.
A note about command-line options: If you runjavadoc -help, you'll see that the Javadoc tool hastwo sets of command-line options. One set is generic and will workwith any doclet. The second set of options is special to thestandard doclet. Options in this second set will not be availablewhen using custom doclets. Your custom doclets can also definetheir own command-line options. See theexample below.
To generate API documentation, a doclet will have to beconsiderably more complex than this simple example. If you want tocustomize the format of the API documentation generated by Javadoc,you may want to start with the default standard doclet and modifyit as necessary rather than write your own doclet from scratch.
For an example, seeHowcan I modify the standard doclet to produce links to source codefrom the API documentation?
method.tags("mytag")would return an array ofTag objects representing any@mytag tags in the method's documentation comment. You canthen access the information in your@mytag tags withTag'stext method. That method returns a string representingthe content of the tag which you can parse or use as needed. Forexample, if a documentation comment contained one of your customtags like this:@mytag Some dummy text.then thetext method would return the string"Somedummy text.".
Here's a standalone doclet (not a subclass of the standarddoclet) that uses these ideas to print out the text associated withall instances of a specified tag that it finds in method comments.It could be extended to find all instances of that tag in allcomments.
import com.sun.javadoc.*;public class ListTags { public static boolean start(RootDoc root){ String tagName = "mytag"; writeContents(root.classes(), tagName); return true; } private static void writeContents(ClassDoc[] classes, String tagName) { for (int i=0; i < classes.length; i++) { boolean classNamePrinted = false; MethodDoc[] methods = classes[i].methods(); for (int j=0; j < methods.length; j++) { Tag[] tags = methods[j].tags(tagName); if (tags.length > 0) { if (!classNamePrinted) { System.out.println("\n" + classes[i].name() + "\n"); classNamePrinted = true; } System.out.println(methods[j].name()); for (int k=0; k < tags.length; k++) { System.out.println(" " + tags[k].name() + ": " + tags[k].text()); } } } } }}The tag for which this doclet searches is specified by the variabletagName. The value of thetagName string can beany tag name, custom or standard. This doclet writes to standardout, but its output format could be modified, for example, to writeHTML output to a file.Any doclet that uses custom options must have a method calledoptionLength(String option) that returns anint.For each custom option that you want your doclet to recognize,optionLength must return the number of separate pieces ortokens in the option. For our example, we want to be able to usethe custom option of the form-tag mytag. This option hastwo pieces, the-tag option itself and its value, so theoptionLength method in our doclet must return2for the-tag option. TheoptionsLength methodshould return0 for unrecognized options.
Here's the full, augmented doclet:
import com.sun.javadoc.*;public class ListTags { public static boolean start(RootDoc root){ String tagName = readOptions(root.options()); writeContents(root.classes(), tagName); return true; } private static void writeContents(ClassDoc[] classes, String tagName) { for (int i=0; i < classes.length; i++) { boolean classNamePrinted = false; MethodDoc[] methods = classes[i].methods(); for (int j=0; j < methods.length; j++) { Tag[] tags = methods[j].tags(tagName); if (tags.length > 0) { if (!classNamePrinted) { System.out.println("\n" + classes[i].name() + "\n"); classNamePrinted = true; } System.out.println(methods[j].name()); for (int k=0; k < tags.length; k++) { System.out.println(" " + tags[k].name() + ": " + tags[k].text()); } } } } } private static String readOptions(String[][] options) { String tagName = null; for (int i = 0; i < options.length; i++) { String[] opt = options[i]; if (opt[0].equals("-tag")) { tagName = opt[1]; } } return tagName; } public static int optionLength(String option) { if(option.equals("-tag")) { return 2; } return 0; } public static boolean validOptions(String options[][], DocErrorReporter reporter) { boolean foundTagOption = false; for (int i = 0; i < options.length; i++) { String[] opt = options[i]; if (opt[0].equals("-tag")) { if (foundTagOption) { reporter.printError("Only one -tag option allowed."); return false; } else { foundTagOption = true; } } } if (!foundTagOption) { reporter.printError("Usage: javadoc -tag mytag -doclet ListTags ..."); } return foundTagOption; }}In this modified doclet, the variabletagName is set withthe command-line option-tag. It has aoptionLength method returns two for our custom option.Note that an explicit call tooptionLength isn't required.This doclet also adds thereadOptions methods thatactually parses the command-line options looking for the-tag option. It makes use of the fact that theRootdoc.options method returns a two-dimensionalString array containing option information. For example, given thecommand
javadoc -foo this that -bar other ...theRootDoc.options method will return
options()[0][0] = "-foo"options()[0][1] = "this"options()[0][2] = "that"options()[1][0] = "-bar"options()[1][1] = "other"The number of elements in the array's second index is determined bytheoptionLength method. In this example,optionLength returns3 for option-fooand returns2 for option-bar.
ThevalidOptions method is an optional method that youcan use to test the validity of the usage of command-line tags. IfthevalidOptions method is present, it is automaticallyinvoked; you don't have to explicitly call it. It should returntrue if the option usage is valid, andfalseotherwise. You can also print appropriate error messages fromvalidOptions when improper usages of command-line optionsare found. ThevalidOptions method in this example docletchecks that the-tag option is used once and onlyonce.