From a16b1b4b227679ab095940ae54bfee7848453b63 Mon Sep 17 00:00:00 2001 From: Roy Golan Date: Tue, 13 Jun 2023 13:59:13 +0300 Subject: [PATCH] Create a doclet that generates a markdown file for a class annotation with @Configuration Scan files with @Configuration and generate .md files: ``` /** * A useful workflow */ @Configuration public class MyWorkflow { } ``` A mvn site or more specifically `mvn javadoc:javadoc ` would generate target/site/MyWorkflow.md: ``` A useful workflow ``` Signed-off-by: Roy Golan --- workflow-examples/pom.xml | 9 ++ .../parodos/examples/doclet/Markdown.java | 141 ++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 workflow-examples/src/main/java/com/redhat/parodos/examples/doclet/Markdown.java diff --git a/workflow-examples/pom.xml b/workflow-examples/pom.xml index d684894cb..c3a5910cf 100644 --- a/workflow-examples/pom.xml +++ b/workflow-examples/pom.xml @@ -208,6 +208,15 @@ org.apache.maven.plugins maven-checkstyle-plugin + + org.apache.maven.plugins + maven-javadoc-plugin + + ${project.basedir}/target/classes + com.redhat.parodos.examples.doclet.Markdown + false + + diff --git a/workflow-examples/src/main/java/com/redhat/parodos/examples/doclet/Markdown.java b/workflow-examples/src/main/java/com/redhat/parodos/examples/doclet/Markdown.java new file mode 100644 index 000000000..3eed9297d --- /dev/null +++ b/workflow-examples/src/main/java/com/redhat/parodos/examples/doclet/Markdown.java @@ -0,0 +1,141 @@ +package com.redhat.parodos.examples.doclet; + +import java.io.IOException; +import java.io.PrintStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +import javax.lang.model.SourceVersion; +import javax.lang.model.element.Element; +import javax.lang.model.util.ElementScanner9; + +import com.sun.source.doctree.DocCommentTree; +import com.sun.source.doctree.UnknownBlockTagTree; +import com.sun.source.util.DocTrees; +import com.sun.source.util.SimpleDocTreeVisitor; +import jdk.javadoc.doclet.Doclet; +import jdk.javadoc.doclet.DocletEnvironment; +import jdk.javadoc.doclet.Reporter; + +public class Markdown implements Doclet { + + private DocTrees treeUtils; + + public Markdown() { + var foo = ""; + } + + @Override + + public void init(Locale locale, Reporter reporter) { + + } + + @Override + public String getName() { + return getClass().getSimpleName(); + } + + @Override + public Set getSupportedOptions() { + return Set.of(); + } + + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + + private static final boolean OK = true; + + @Override + public boolean run(DocletEnvironment environment) { + treeUtils = environment.getDocTrees(); + ShowTags st = new ShowTags(System.out); + st.show(environment.getSpecifiedElements()); + return OK; + } + + /** + * A scanner to search for elements with documentation comments, and to examine those + * comments for custom tags. + */ + class ShowTags extends ElementScanner9 { + + final PrintStream out; + + ShowTags(PrintStream out) { + this.out = out; + } + + void show(Set elements) { + scan(elements, 0); + } + + @Override + public Void scan(Element e, Integer depth) { + DocCommentTree dcTree = treeUtils.getDocCommentTree(e); + if (dcTree != null) { + String indent = " ".repeat(depth); + out.println(indent + "| " + e.getKind() + " " + e + " annotations has configuration " + + e.getAnnotationMirrors().toArray().toString()); + + if (e.getAnnotationMirrors().stream() + .anyMatch(a -> a.toString().equals("@org.springframework.context.annotation.Configuration"))) { + try { + Files.write(Paths.get(e.getSimpleName() + ".md"), dcTree.getFullBody().toString().getBytes()); + } + catch (IOException ex) { + throw new RuntimeException(ex); + } + } + Map> tags = new TreeMap<>(); + new TagScanner(tags).visitDocComment(dcTree, null); + tags.forEach((t, l) -> { + out.println(indent + " @" + t); + l.forEach(c -> out.println(indent + " " + c)); + }); + } + // records are not supported by the tool for some reason. Probably a javadoc + // bug. + if (e.getKind().toString().equals("RECORD")) { + return null; + } + return super.scan(e, depth + 1); + } + + } + + /** + * A visitor to gather the block tags found in a comment. + */ + class TagScanner extends SimpleDocTreeVisitor { + + private final Map> tags; + + TagScanner(Map> tags) { + this.tags = tags; + } + + @Override + public Void visitDocComment(DocCommentTree tree, Void p) { + return visit(tree.getBlockTags(), null); + } + + @Override + public Void visitUnknownBlockTag(UnknownBlockTagTree tree, Void p) { + String name = tree.getTagName(); + String content = tree.getContent().toString(); + tags.computeIfAbsent(name, n -> new ArrayList<>()).add(content); + return null; + } + + } + +} \ No newline at end of file