The Source for Java Technology Collaboration
User: Password:



   

Improve on Javadocs with <i>ashkelon</i> Improve on Javadocs with ashkelon

by Eitan Suez
08/26/2004


Contents
A Database of Docs
More Than a Collection of Loosely Connected APIs
A Formal Definition for an API
A Different User Interface?
Final Thoughts

Sun's Javadocs provide us with automatically generated, hyperlinked documentation of fields, methods, classes, interfaces, and inner classes. They are helpful in many ways, but you will soon develop a wish list that includes the ability to search for programming elements, the ability to access multiple APIs from one location, the ability to cross-reference relationships across APIs. The list goes on.

This article describes ashkelon, an open source documentation system for Java that leverages Sun's Javadoc parser. When developing a UI for, say, 50 APIs, 500 packages, 10,000 classes, and 100,000 methods, how do you present mounds of information in a readily accessible and intelligible way? Patrick Chan's solution was to produce the Java Almanac, containing indices and cross-references to programming elements. But there are drawbacks to paper forms of referencing; for one thing, the Java Almanac covers only J2SE. And it's long and heavy.

The handful of techniques used repeatedly in ashkelon's UI to address this problem are:

  1. Hide information on the page using CSS display and visibility properties, and toggle those properties dynamically (using various DHTML client-side "widgets" such as tabs, collapsible trees, and filtered tables).

  2. Color code, for more natural filtering of information on the page.

  3. Minimize scrolling.

  4. Provide many ways to access the same information: via an index, browsing or searching, temporal navigation back to an element recently previewed, via a cross-reference, or another type of programmatic relationship such as a throws relationship.

A Database of Docs

One component of ashkelon plugs in to Javadoc as a doclet to populate a relational database with Javadocs. The corresponding database schema for the Java language consists of tables with names such as member, classtype, package, author, field, parameter, method, and thrownexception. The schema can be updated and grow to include changes such as those introduced with J2SE 5.0 and aspects.

So what can you do with a database schema filled with Javadocs? For one thing, with ashkelon you can populate multiple APIs into a single repository. You can do this incrementally, too. That is, you don't have to add all APIs in one run to "get your links." Let's look at how we might use ashkelon to populate an API such as Hibernate into the database. Invoke the following command from the command line, in much the same way as you would use the Javadoc tool to produce HTML documentation:

~$ ashkelon add @hibernate.xml

To add another API (say dom4j), you do this:

~$ ashkelon add @dom4j.xml

Now we can ask ashkelon to list the APIs in its database:

~$ ashkelon list

which, with my local copy of ashkelon running on my notebook computer today, produces:

Ashkelon: API: Ashkelon
Ashkelon: API: Hibernate
Ashkelon: API: J2SE
Ashkelon: API: JTidy
Ashkelon: API: JUnit
Ashkelon: API: JiBX
Ashkelon: API: Servlet 2.3 & JSP 1.2
Ashkelon: API: dom4j

I happen to be running my local copy of ashkelon against PostgreSQL. The jdocs.org site chose to run ashkelon with MySQL. (I've also recently added support for mckoidb, a lightweight database written in Java.)

ashkelon's design decision to use a database gives it intimate knowledge of the code. It enables it to answer intelligent questions, such as: "list all methods that return objects of a certain type," "list all classes that implement a certain interface," "list all direct subclasses of a certain class," and so on.

More Than a Collection of Loosely Connected APIs

ashkelon makes a major effort to truly integrate the multiple APIs that reside in its repository.

Each time you add an API, a cross-referencing step takes place after the "store" step to update inter-API references between programming elements. Here's an example. Assume you already have the W3C's DOM API populated and then decide to add Hibernate. Look up this Hibernate method:

public org.w3c.dom.Document toGenericDOM()
           throws net.sf.hibernate.HibernateException

Using ashkelon's web-based UI, you'd find that the return type (org.w3c.dom.Document) is hyperlinked.

Inter-API integration can also be seen in the cross-reference section of ashkelon's UI. All classes and interfaces in the ashkelon system have a cross-reference tab, shown in Figure 1.

Figure 1. GUI view of cross-linking
Figure 1. GUI view of cross-linking

For example, you can ask ashkelon to list all methods that return a org.w3c.dom.Document. The results, shown in Figure 2, include methods from various APIs: hibernate, dom4j, javax.xml, org.w3c.tidy, and of course, org.w3c.xml.

Figure 2. Search for occurrences of a class
Figure 2. Search for occurrences of a class

A third place where this integration is evident is in search results. A class search for "*Writer" will produce a listing that includes these classes or interfaces: org.jibx.runtime.IXMLWriter, org.dom4j.io.XMLWriter, javax.swing.text.html.HTMLWriter, java.io.Writer, and javax.sql.RowSetWriter.

A Formal Definition for an API

Digging a little deeper, let's return to that add command. We had to feed it an XML file: hibernate.xml or dom4j.xml. What's that all about? With the original Javadoc tool, you typically feed it the name of a file that contains the listing of packages that you want to document. Being a multi-API repository, ashkelon needs to invent one more level up the containment hierarchy: the API.

These XML files are nothing more than information about the project you want to document. Those of you familiar with Maven are also familiar with its definition of a project XML file, known as the Project Object Model (POM). As of version 0.8.7, ashkelon understands the Maven POM file format and can use these project.xml files as input for populating APIs into its database repository. Here's how one populates dom4j's API using its project.xml file:

~$ ashkelon add @project.xml

This makes the population of APIs trivial and effortless for projects that use Maven. Alternatively, ashkelon defines its own XML file format for APIs. Below are the contents of dom4j.xml.

<?xml version="1.0" ?>
<api>
 <name>dom4j</name>
 <summarydescription>The flexible XML framework for Java</summarydescription>
 <description>dom4j is an easy to use, open source
 library for working with XML, XPath and XSLT on the Java 
 platform using the Java Collections Framework and with
 full support for DOM, SAX and JAXP.</description>
 <publisher>SourceForge</publisher>
 <download_url>http://www.dom4j.org/</download_url>
 <release_date>2004-05-12T08:00:00</release_date>
 <version>1.4</version>
 <package>org.dom4j</package>
 <package>org.dom4j.bean</package>
 <package>org.dom4j.datatype</package>
 <package>org.dom4j.dom</package>
 <package>org.dom4j.dtd</package>
 <package>org.dom4j.io</package>
 <package>org.dom4j.io.aelfred</package>
 <package>org.dom4j.persistence</package>
 <package>org.dom4j.persistence.nativ</package>
 <package>org.dom4j.rule</package>
 <package>org.dom4j.rule.pattern</package>
 <package>org.dom4j.swing</package>
 <package>org.dom4j.tree</package>
 <package>org.dom4j.util</package>
 <package>org.dom4j.xpath</package>
 <package>org.dom4j.xpp</package>
</api>

There's no need to write this XML file by hand. For one thing, ashkelon comes "out of the box" with approximately 32 pre-written API XML files for various popular open source projects including Ant, J2SE, Hibernate, dom4j, and many more. Secondly, ashkelon comes with a script, called apixml, that will automatically produce the XML file, directly from a Javadoc package-list file:

~/devel/dom4j-1.4/doc/javadoc $ apixml package-list

which produces this output (to stdout):

<?xml version="1.0" ?>
<api>
<name></name>
<summarydescription></summarydescription>
<description></description>
<publisher></publisher>
<download_url></download_url>
<release_date>2001-07-03T08:00:00.000</release_date>
<version></version>
<package>org.dom4j</package>
<package>org.dom4j.bean</package>
<package>org.dom4j.datatype</package>
<package>org.dom4j.dom</package>
<package>org.dom4j.dtd</package>
<package>org.dom4j.io</package>
<package>org.dom4j.io.aelfred</package>
<package>org.dom4j.persistence</package>
<package>org.dom4j.persistence.nativ</package>
<package>org.dom4j.rule</package>
<package>org.dom4j.rule.pattern</package>
<package>org.dom4j.swing</package>
<package>org.dom4j.tree</package>
<package>org.dom4j.util</package>
<package>org.dom4j.xpath</package>
<package>org.dom4j.xpp</package>
</api>

Finally, fill in the missing pieces (API name, description, publisher, etc.), which you can look up on the project's home page.

Pages: 1, 2

Next Page » 

View all java.net Articles.

 Feed java.net RSS Feeds