|
|
||||||||||||||||||||||||||||||||||||||||||||
For our new PowerPoint rendering library, I needed access to some
internal methods in a package from another product. Making the method
public didn't seem like a good solution, though, because it would affect
the published API, which we didn't want to do. I had read Martin Fowler's
paper (PDF)
on need for a distinction between public and published interfaces before,
and now I finally understood what he meant. ![]()
But since this was just a single method, I figured I would just hack
around it by excluding that particular method from our javadoc. You
know, something like an @exclude tag. To make a long
story short: "There is currently no Javadoc option to hide, exclude or suppress public members from the javadoc-generated documentation" (from the javadoc FAQ), even though it is a proposed tag and the most requested javadoc enhancement.
As it turns out, there is a relatively simple way to implement
@exclude. The basic idea is to implement a
Doclet that delegates to Sun's standard doclet as necessary, while filtering out all the excluded classes/fields/methods from method return values. For example, the ClassDoc methods() method returns an array of MethodDoc objects. By wrapping the ClassDoc in a proxy and intercepting all method calls we can filter out excluded methods from the array before returning from the method.
Thankfully the Doclet API is very interface-based, so
Dynamic
Proxies are an option. Otherwise I might have to use
CGLIB, bleh! ![]()
com.sun.* object, including array elements.compareTo, overrides, and subclassOf) we need special code to unwrap the argument before calling the underlying method.Actually using the doclet is really simple--just add a
doclet="com.tonicsystems.doclet.ExcludeDoclet"
(and docletref) to the appropriate Ant task. On JDK 1.4 you
may get some strange warnings printed:
Internal error: package sets don't match: [] with: null Internal error: package sets don't match: [] with: null ...etc...
As far as I can tell, these "errors" do not affect the output. If someone knows better, I'd like to hear about it. Anyway, in JDK 1.5 they have disappeared altogether, perhaps as part of the standard doclet refactoring.
The full source for ExcludeDoclet is here. It's in the public domain, so go crazy.