JavaDoc 编程,书写自定义的 Taglet 支持 @unmi 等

javadoc 可为我们的 Java 项目生成 API 文档,别人的应该是看得多了,自己的可能不好意思晾出来看。那 Java 源代码里的 @author, @see, @param 等应该是司空见惯了吧。除此之外我们还可以自定义自己的 tag,并让它们的内容按照我们需要的格式生成到 javadoc 文档中,或作他用。还记得没有 Maven 的时代我们是怎样用 XDoclet 生映射文件的吗?现在的 Taglet 定制想要做的事情大抵如此。

执行一下 javadoc 命令看看,一堆的参数可以指定,又有学问在里头,且看:

-tag <name>:<locations>:<header>  Specify single argument custom tags
-taglet                           The fully qualified name of Taglet to register
-tagletpath                       The path to Taglets

-doclet <class>           Generate output via alternate doclet
-docletpath <path>        Specify where to find doclet class files

关于 doclet 部份这儿暂且不说,单讲 tag 部分的东西。

对于自定义 tag,简单的时候,用参数 -tag  都可以不写自己的 taglet 类,例如有这样一个代码:

上面使用了 @document 自定义 tag,要为它生成文档,可以用命令:

javadoc -tag document:a:Document: *.java

于是生成的 javadoc 文档中有了:

taglet_1

-tag 参数的 name, header 部分一对照就知道了,中间那个 location 参数代表修饰谁的注释要被解析,取值有:

X (disable tag)
a (all)
o (overview)
p (packages)
t (types, that is classes and interfaces)
c (constructors)
m (methods)
f (fields)

上面的 -tag 为 @document 生成的 HTML  是:

如果我们要为前面的 @document 生成更具表现力说明,或是另有企图 -- 如提取 @document 后的内容生成自己的外部文件中,那现在就得让 Taglet 登场了。从 DocumentTaglet 代码开始,它需要实现 com.sun.tools.doclets.Taglet 接口,要实现它所有的方法。里面有一片的 inField(),inMethod() 等方法,若返回 true 则表示这个标签可作用于这个位置上。

那什么是 isInlineTag() 呢,下面这样写的注释就是 Inline Tag: 用大括号括起来的就是 Inline tag,这时取的 tag.text() 就只是 "help"   了。你自己决定 isInlineTag() 方法返回 true 还是 false 吧。

还有那个注册方法,需 Taglet 接口中没有,但却是一定要写的,方法原型是:

public static void register(Map<String, Taglet> tagletMap),用来注册要用到的所有 Taglet, 也就是可在此一个个指定什么 tag 由哪一个类来处理。其实这里的 DocumentTaglet 可不实现 Taglet, javadoc -taglet 指定为这个类后所要做的工作就是执行该类的 register(Map<String, Taglet> tagletMap) 方法,至于后面碰到了某个 tag 时才真正去调用对应 Taglet 类的 toString 方法。

也就是说在这个 register 方法中可以同时注册多个  Taglet 类实例。这种情况下把现在的 DocumentTaglet 更名为 CustomTags 意义就更准确些。

关键是那两个 toString() 方法,它的返回值就是要交给 javadoc 显示出来的内容,文章要在这儿做。

把重要的代码前移了,因为用到了 tools.jar 包,所以编译时需把 JDK 目录中的 tools.jar 加到 classpath 上去。实际测试中不管为一个方法写一个还是多个 @document 注释,javadoc 都是直接命中 toString(Tag[] tags) 方法。

要是想在 toString(Tag[] tags) 方法中得到被注释的元素的信息,就从 Tag 类型出发,tag.holder() 得到一个 Doc,对应注释的位置,它可能是一个 MethodDoc, ClassDoc, FieldDoc, PackageDoc 等,所以当前被注释元素的信息便可由此而得。

在假设编译后的 DocumentTaglet.class 文件在 c:/javadoc_taglet/bin/cc/unmi/taglet 目录下,你可以用下面的命令为前面那个 TestJavaDocTag.java 生成 javadoc 文档:

javadoc -taglet cc.unmi.taglet.DocumentTaglet -tagletpath c:/javadoc_taglet/bin

生成的 javadoc 的效果就是, @document 的值提取出来,并渲染为红色字体显示:

taglet_2

我们在生成 javadoc 时,会得到提示:

Note: Custom tags that could override future standard tags:  @document. To avoid
 potential overrides, use at least one period character (.) in custom tag names.

那是 javadoc 怕 @document 会与别人重复,希望你能加个命名空间,如写成 @unmi.document 这样子。

tools.jar 中还有另外一个 Taglet(com.sun.tools.doclets.internal.toolkit.taglets.Taglet) 接口,尚不知作用何的,Doclet 吗?接着有空也看看 -doclet 参数的应用定制。

参考:1. javadoc - The Java API Documentation Generator
          2. Taglet Overview
          3. Javadoc Programming
          4. Taglets Collection

本文链接 https://yanbin.blog/javadoc-programming-customize-taglet/, 来自 隔叶黄莺 Yanbin Blog

[版权声明] Creative Commons License 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。

Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments