Crear anotaciones de Javadoc personalizadas con taglets

Escrito por el .
blog-stack java planeta-codigo" programacion
Comentarios

Java

La herramienta de documentación es Javadoc de Java permite a partir del código fuente de un programa o librería generar un conjunto de documentos en formato HTML enlazados entre si consultables con un navegador web y accesibles desde internet si son accesibles con un servidor web. La documentación se genera a partir de las clases y métodos del código fuente y también a partir de los comentarios de las clases y métodos.

En los comentarios se pueden incluir anotaciones que enriquecen la documentación, por ejemplo, para indicar el autor o en qué versión se incluyó una clase o método, incluir enlaces, … en el propio JDK ya se incluye un amplio conjunto completo de anotaciones. Pero además de usar las anotaciones ya incorporados por defecto en la herramienta también es posible añadir nuevos propios, escribiendo un taglet. Con la API de los taglets basta implementar una clase que implemente la interfaz Taglet. La interfaz Taglet de Java 9 ha sido modificada ligeramente pero en esencia proporciona la misma información, en vez de un método para indicar si es posible el taglet en una localización hay un único método que devuelve un Set con todas las posibles localizaciones, en vez de necesitar un método register hay un método init y un único método para generar el contenido, toString.

La clase tiene varios métodos uno que indica el nombre único del taglet que identificará la anotación en los comentarios de Javadoc, varios métodos para indicar en que localizaciones es usable y dos métodos que generan el contenido a incluir en el HTML resultante. Las clases Tag que recibe el método Taglet.toString() o ParamTag permite obtener diversa información utilizable para generar el contenido apropiado.

Los taglets pueden ser de tipo bloque con su propia entidad o ser embebidos en linea en un comentario del javadoc. En ejemplo de taglet de bloque siguiente consiste en permitir incluir elementos que quedan por hacer en el código, una anotación todo. Con esta anotación el desarrollador incluye un comentario descriptivo de cuales son las cosas pendientes para un futuro. El código del taglet sería el siguiente.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package io.github.picodotdev.blogbitix.javadoc;

import com.sun.tools.doclets.Taglet;
import com.sun.javadoc.Tag;
import java.util.Map;

/**
 * A sample Taglet representing @todo. This tag can be used in any kind of
 * {@link com.sun.javadoc.Doc}.  It is not an inline tag. The text is displayed
 * in yellow to remind the developer to perform a task. For
 * example, "@todo Fix this!" would be shown as.
 *
 * @author picodotdev
 */
public class TodoTaglet implements Taglet {

    private static final String NAME = "todo";
    private static final String HEADER = "To do:";

    public String getName() {
        return NAME;
    }

    public boolean inField() {
        return true;
    }

    public boolean inConstructor() {
        return true;
    }

    public boolean inMethod() {
        return true;
    }

    public boolean inOverview() {
        return true;
    }

    public boolean inPackage() {
        return true;
    }

    public boolean inType() {
        return true;
    }

    public boolean isInlineTag() {
        return false;
    }

    public static void register(Map tagletMap) {
       TodoTaglet tag = new TodoTaglet();
       Taglet t = (Taglet) tagletMap.get(tag.getName());
       if (t != null) {
           tagletMap.remove(tag.getName());
       }
       tagletMap.put(tag.getName(), tag);
    }

    public String toString(Tag tag) {
        return "<b>" + HEADER + "</b><span style=\"background-color: yellow;\">" + tag.text() + "</span>\n";
    }

    public String toString(Tag[] tags) {
        if (tags.length == 0) {
            return null;
        }

        String result = "<b>" + HEADER + "</b><ul>" ;
        for (Tag tag : tags) {
            result += "<li><span style=\"background-color: yellow;\">" + tag.text() + "</span></li>";
        }
    result += "</ul>";
        return result;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package io.github.picodotdev.blogbitix.javadoc;

/**
 * Clase main de la aplicación.
 *
 * @see <a href="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html">Javadoc</a>
 * @see <a href="https://docs.oracle.com/javase/8/docs/api/">Javadoc JDK</a>
 * @author picodotdev
 * @version 1.0
 *
 * @todo <span style="text-decoration: line-through;">Implementar in taglet personalizado</span>
 * @todo Añadir estilos al javadoc
 */
public class Main {

    /**
     * Método que imprime un mensaje.
     * 
     * @param args Argumentos del programa
     *
     */
    public static void main(String[] args) {
      System.out.println("Hola mundo");
    }
}
} Una vez escrito el código fuente del _taglet_ hay que compilarlo e indicar su ubicación al generar la documentación con la herramienta _javadoc_. Hay que indicar varias opciones (_tagletPath_ y _taglets_) que también se usarían como parámetros empleando directamente la herramienta _javadoc_, los comandos serían los siguientes usando [Gradle][gradle]. También hay que incluir de forma explícita como dependencia la librería _tools.jar_ ubicado en el JDK.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
apply plugin: 'java'
apply plugin: 'application'

sourceCompatibility = 1.8
targetCompatibility = 1.8

mainClassName = 'io.github.picodotdev.blogbitix.javadoc.Main'

repositories {
    jcenter()
}

dependencies {
    compile files("/usr/lib/jvm/default/lib/tools.jar")
}

javadoc {
    options.charSet = 'UTF-8'
    options.encoding = 'UTF-8'
    options.tagletPath = [new File ('build/classes/java/main/')]
    options.taglets = ['io.github.picodotdev.blogbitix.javadoc.TodoTaglet']
}

task javadocZip(type: Zip) {
    dependsOn javadoc
    classifier 'javadoc'
    from 'build/docs/javadoc/'
}

artifacts {
    archives javadocZip
}

}
Contenido del taglet todo en el javadoc

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando el comando ./gradlew javadoc.