Skip to main content

Tip: Javadoc as XML

Use Javadoc XML output for reports

Jack Herrington (jherr@pobox.com), Editor-in-Chief, Code Generation Network
An engineer with with more than 20 years of experience, Jack Herrington is currently Editor-in-Chief of the Code Generation Network. He is the author of Code Generation in Action . You can contact him at jack_d_herrington@codegeneration.net.

Summary:  A lot of value is locked up in your Java code: all your classes and interfaces, as well as their instance variables and methods. You can use these data to create documentation, to build code generators, or to provide metrics for project reporting.

View more content in this series

Date:  14 Apr 2005
Level:  Intermediate
Activity:  2535 views

The Javadoc tool is a very well-factored application. Many people think it?s just a program that creates HTML from reading the code and comments in a set of Java™ files. But in reality, the tool is divided into two sections. The first is the code-analysis engine, which parses the code and the comments. The second generates the HTML, but as it turns out, you can change that section with extensions called doclets.

For this tip, I use JELDoclet (see Resources) to generate an XML output file from a set of test Java files. Then, I use XSL to format the XML into a simple HTML file that demonstrates what data are in the XML file.

After downloading JELDoclet, I run it on a set of files using the following syntax:

javadoc -doclet JELDoclet -docletpath .. *.java

The test directory of JELDoclet includes a set of test Java files. This command parses all the Java files in the test directory and creates a file called out.xml, which contains all the information in the Javadoc tree. Listing 1 shows a portion of this output XML file.


Listing 1. The JELDoclet output XML file
                
<jel>
<class superclass="Object" name="MyInterClass">
  <extend name="MyInterface">
  </extend>
  <comment>
  My interface implemented
  </comment>
  <fields>
    <field visibility="protected"
     fulltype="java.lang.String"
     type="String" name="_prot_string">
       <comment>
       A protected string
       </comment>
    </field>
    <field visibility="public"
     fulltype="java.lang.String"
     type="String" name="_pub_string">
       <comment>
       A public string
       </comment>
    </field>
  </fields>
  <methods>
    <constructor visibility="public" name="MyInterClass">
       <comment>
       A no-argument constructor
       </comment>
    </constructor>
    <constructor visibility="public" name="MyInterClass">
       <params>
         <param fulltype="java.lang.String"
          type="String" comment="A string."
          name="aString">
         </param>
...

The jel tag contains a series of class tags -- one for each class. Within the class tags are the fields, methods, and constructors. The XML file also includes the associated comments.

Create HTML from the XML

Your first step toward generating the HTML for this XML (in Listing 1) is to start with the base tag template in Listing 2.


Listing 2. The base HTML template
                
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
 xmlns:xsl=http://www.w3.org/1999/XSL/Transform
 version="2.0">

<xsl:output method="html" />

<xsl:template match="/">
  <html><head><title>XDoclet output</title>
  <xsl:call-template name="css" />
  </head>
  <body>
    <xsl:for-each select="/jel/class">

      <h1>
        <xsl:choose>
          <xsl:when test="@abstract='true'">Interface:
          <xsl:value-of select="@name" /></xsl:when>
          <xsl:otherwise>Class
          : <xsl:value-of select="@name" />
           ( <xsl:value-of select="@superclass" /> )
          </xsl:otherwise>
        </xsl:choose>
      </h1>

      <h2>Instance Variables</h2>
      <xsl:apply-templates select="fields/field" />

        <h2>Constructors</h2>
        <xsl:apply-templates select="methods/constructor" />

      <h2>Methods</h2>
      <xsl:apply-templates select="methods/method" />

      <hr/>
    </xsl:for-each>
  </body>
  </html>
</xsl:template>

In the first section, I create the html root tag and the head section. Then, I iterate through every class in the input file. For each class, I output the class or interface name in an h1 tag and apply templates for the fields, constructors, and methods. Then, I wrap it all up by closing the body and html tags.

The template for building the field HTML is very simple, as Listing 3 shows.


Listing 3. The field template
                
<xsl:template match="field">
  <p class="field">
    <xsl:value-of select="@visibility" />
    <xsl:text> </xsl:text>
    <xsl:value-of select="@type" />
    <xsl:text> </xsl:text>
    <xsl:value-of select="@name" />
  </p>
</xsl:template>

Pretty simple stuff: I just output the visibility, the type, and the name. I bracket that in a paragraph tag with the class field, which I?ll use later in the CSS.

The method and constructor templates are similar to the field template, as Listing 4 shows.


Listing 4. The method and constructor templates
                
<xsl:template match="method">
  <p class="method">
    <xsl:value-of select="@visibility" />
    <xsl:text> </xsl:text>
    <xsl:value-of select="@type" />
    <xsl:text> </xsl:text>
    <xsl:value-of select="@name" />(
    <xsl:apply-templates select="params" />
  )</p>
</xsl:template>

<xsl:template match="constructor">
  <p class="method">
    <xsl:value-of select="@visibility" />
    <xsl:text> </xsl:text>
    <xsl:value-of select="@name" />(
    <xsl:apply-templates select="params" />
  )</p>
</xsl:template>

The only trick here is that I need to output the list of parameters to each constructor or method. I do this with the xsl:apply-templates tag, which finds the correct template for the params tag -- in this case, the template shown in Listing 5.


Listing 5. The params template
                
<xsl:template match="params">
 <xsl:for-each select="param">
  <xsl:if test="position()>1">, </xsl:if>
  <xsl:value-of select="@type" /><xsl:text> </xsl:text>
  <xsl:value-of select="@name" />
 </xsl:for-each>
</xsl:template>

The interesting part here is that I want commas between the parameters in the list, so I use the xsl:if directive to insert a comma only if I?m on the second parameter or later.

The last part of the XSL template is the CSS portion, which makes the output a bit more readable (see Listing 6).


Listing 6. The CSS template
                
<xsl:template name="css">
<style>
    body { font-family: Arial, Verdana, sans serif;
       font-size: small; }
    .method, .field { padding-left:50px; }
</style>
</xsl:template>
    
</xsl:stylesheet>
        

Use sans-serif fonts like Arial or Verdana to make the output more readable. You might use Courier, but I think it makes the page look drab and gives the impression that it was written on an old typewriter. The final output looks like that in Figure 1.


Figure 1. The resultant HTML in a browser
The resultant HTML

Summary

Formatting HTML is just one of the things you can do with XML output from the Javadoc tool. You can use the information in the Javadoc tree (exported here as XML) to power code generators, as XDoclet does. You can perform code-reference analysis and refactoring like Eclipse or IntelliJ. You can also get metrics on your code base. Having a complete, structured representation of your Java code in XML is a powerful tool that can help increase your productivity.


Resources

About the author

An engineer with with more than 20 years of experience, Jack Herrington is currently Editor-in-Chief of the Code Generation Network. He is the author of Code Generation in Action . You can contact him at jack_d_herrington@codegeneration.net.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=XML, Java technology
ArticleID=59056
ArticleTitle=Tip: Javadoc as XML
publish-date=04142005
author1-email=jherr@pobox.com
author1-email-cc=

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Special offers