io.nosqlbench.virtdata.userlibs.apps.docsapp.AutoDocsApp Maven / Gradle / Ivy
package io.nosqlbench.virtdata.userlibs.apps.docsapp;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.vladsch.flexmark.convert.html.FlexmarkHtmlParser;
import io.nosqlbench.virtdata.annotations.Category;
import io.nosqlbench.virtdata.api.VirtDataDocs;
import io.nosqlbench.virtdata.processors.DocCtorData;
import io.nosqlbench.virtdata.processors.DocFuncData;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import java.io.*;
import java.security.InvalidParameterException;
import java.util.*;
import java.util.stream.Collectors;
public class AutoDocsApp {
private final static Logger logger = LogManager.getLogger(AutoDocsApp.class);private final static String SPLIT = "split";
private final static String COMBINED = "combined";
private final static String ALL = "all";
private final static String DEFAULT_FILE = "funcref";
private static final String MARKDOWN = "markdown";
private static final String JSON = "json";
// category -> funcname -> [docfuncdata, ...]
private Map>> groupedModels = new HashMap<>();
private String baseFileName = DEFAULT_FILE;
private String print = ALL;
private String categories = SPLIT;
private String format = MARKDOWN;
public static void main(String[] args) {
new AutoDocsApp().invoke(args);
}
private void invoke(String[] args) {
LinkedList largs = new LinkedList<>(Arrays.asList(args));
while (largs.peekFirst() != null) {
String argtype = largs.removeFirst();
if (largs.peekFirst() == null) {
throw new RuntimeException(AutoDocsApp.class.toString() + " expects args in param value couplets.");
}
String argval = largs.removeFirst().toLowerCase();
switch (argtype) {
case "output":
this.baseFileName = argval;
break;
case "print":
if (argval.equals("all") || argval.equals("logs")) {
this.print = argval;
} else {
throw new InvalidParameterException("valid args for print: print all, print logs");
}
case "categories":
if (!argval.equals(SPLIT) && !argval.equals(COMBINED)) {
throw new RuntimeException("categories must either be " + SPLIT + ", or " + COMBINED + ".");
}
this.categories = argval;
break;
case "format":
if (!argval.equals(MARKDOWN) && !argval.equals(JSON)) {
throw new RuntimeException("format must either be " + MARKDOWN + ", or " + JSON + ".");
}
this.format = argval;
break;
default:
}
}
List docModels = VirtDataDocs.getAllDocs();
for (DocFuncData docModel : docModels) {
for (Category category : docModel.getCategories()) {
Map> category_funcname_list = this.groupedModels.get(category);
if (category_funcname_list == null) {
category_funcname_list = new HashMap<>();
this.groupedModels.put(category, category_funcname_list);
}
List group = category_funcname_list.getOrDefault(docModel.getClassName(), new ArrayList<>());
group.add(docModel);
category_funcname_list.put(docModel.getClassName(), group);
}
}
// StringBuilder sb = new StringBuilder();
// Map docsByCategory=new HashMap<>();
Map> assignments = new HashMap<>();
// Map single category annotation to global Name -> Category assignment
for (DocFuncData docModel : docModels) {
Set listForFuncName = assignments.getOrDefault(docModel.getClassName(), new HashSet<>());
assignments.put(docModel.getClassName(), listForFuncName);
if (listForFuncName.size() > 0) {
logger.warn("Func name " + docModel.getClassName() + " has " + listForFuncName.size() + " multiple category annotations:");
}
listForFuncName.addAll(Arrays.asList(docModel.getCategories()));
logger.info("Assigning " + docModel.getClassName() + " to categories " + listForFuncName.toString());
}
Set generalSet = new HashSet<>() {{
add(Category.general);
}};
// regroup docs under categories
// category -> funcname -> [docfuncdata, ...]
Map>> regrouped = new HashMap<>();
for (DocFuncData docModel : docModels) {
Set assignment = assignments.getOrDefault(docModel.getClassName(), generalSet);
if (assignment.size() == 0) {
assignment = generalSet;
}
logger.info("looking up assignment for " + docModel.getClassName() + ":" + assignment.toString());
for (Category category : assignment) {
Map> assignToCategory = regrouped.getOrDefault(category, new HashMap<>());
regrouped.put(category, assignToCategory);
List assignToClass = assignToCategory.getOrDefault(docModel.getClassName(), new ArrayList<>());
assignToCategory.put(docModel.getClassName(), assignToClass);
assignToClass.add(docModel);
}
}
groupedModels = regrouped;
Map writers = new HashMap<>();
Writer writer = new OutputStreamWriter(System.out);
try {
String extension = (this.format.equals(MARKDOWN)) ? ".md" : ".json";
for (Category category : Category.values()) {
if (groupedModels.keySet().contains(category)) {
if (!this.baseFileName.isEmpty() && this.categories.equals(SPLIT)) {
writer = writers.getOrDefault(category.toString(), new FileWriter(baseFileName + "_" + category.toString() + extension));
} else if (!this.baseFileName.isEmpty() && this.categories.equals(COMBINED)) {
writer = writers.getOrDefault(baseFileName + extension, new FileWriter(baseFileName));
}
String docs = writeCategoryDocs(category, groupedModels.get(category));
//docs = replacePatterns(docs);
writer.write(docs);
writer.flush();
}
}
for (Writer writer1 : writers.values()) {
writer1.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private String writeCategoryDocs(Category category, Map> groupedDocs) {
StringBuilder sb = new StringBuilder();
ArrayList funcNames = new ArrayList<>(groupedDocs.keySet());
Collections.sort(funcNames);
List fdocs = new ArrayList<>(groupedDocs.size());
for (String name : funcNames) {
FunctionDoc fdoc = new FunctionDoc(name);
List docs = groupedDocs.get(name);
List classdocs = docs.stream()
.filter(d -> d.getClassJavadoc() != null && !d.getClassJavadoc().isEmpty())
.collect(Collectors.toList());
List distinctClassDocs = classdocs.stream()
.map(DocFuncData::getClassJavadoc)
.map(String::trim)
.distinct()
.collect(Collectors.toList());
if (distinctClassDocs.size() == 0) {
logger.warn("There were no class docs found for types named " + name);
}
if (distinctClassDocs.size() > 1) {
logger.warn("There were multiple class docs found for types named " + name);
}
if (distinctClassDocs.size() == 1) {
String classdoc = distinctClassDocs.get(0);
classdoc = parseHtmlToMarkdown(classdoc);
sb.append(classdoc);
if (!classdoc.endsWith("\n")) {
classdoc=classdoc + "\n";
}
if (!classdoc.endsWith("\n\n")) {
classdoc=classdoc + "\n";
}
fdoc.setClassDocs(classdoc);
}
for (DocFuncData doc : docs) {
fdoc.addCategories(doc.getCategories());
for (DocCtorData ctor : doc.getCtors()) {
fdoc.addCtor(ctor);
}
}
fdocs.add(fdoc);
}
if (format.equals(MARKDOWN)) {
sb.append("# CATEGORY ").append(category).append("\n");
for (String name : funcNames) {
List docs = groupedDocs.get(name);
sb.append("## ").append(name).append("\n\n");
List classdocs = docs.stream()
.filter(d -> d.getClassJavadoc() != null && !d.getClassJavadoc().isEmpty())
.collect(Collectors.toList());
List distinctClassDocs = classdocs.stream()
.map(DocFuncData::getClassJavadoc)
.map(String::trim)
.distinct()
.collect(Collectors.toList());
if (distinctClassDocs.size() == 0) {
logger.warn("There were no class docs found for types named " + name);
}
if (distinctClassDocs.size() > 1) {
logger.warn("There were multiple class docs found for types named " + name);
}
if (distinctClassDocs.size() == 1) {
String classdoc = distinctClassDocs.get(0);
classdoc = parseHtmlToMarkdown(classdoc);
sb.append(classdoc);
if (!classdoc.endsWith("\n\n")) {
sb.append("\n");
}
if (!classdoc.endsWith("\n")) {
sb.append("\n");
}
}
for (DocFuncData doc : docs) {
List ctors = doc.getCtors();
for (DocCtorData ctor : ctors) {
sb.append("- ").append(doc.getInType()).append(" -> ");
sb.append(doc.getClassName());
sb.append("(");
sb.append(
ctor.getArgs().entrySet().stream().map(
e -> e.getValue() + ": " + e.getKey()
).collect(Collectors.joining(", "))
);
sb.append(")");
sb.append(" -> ").append(doc.getOutType()).append("\n");
String ctorDoc = ctor.getCtorJavaDoc();
if (!ctorDoc.isEmpty()) {
sb.append(" - *notes:* ").append(ctorDoc);
}
for (List example : ctor.getExamples()) {
sb.append(" - *ex:* `").append(example.get(0)).append("`");
if (example.size() > 1) {
sb.append(" - *").append(example.get(1)).append("*");
}
sb.append("\n");
}
}
}
sb.append("\n");
sb.append("\n");
}
} else if (format.equals(JSON)) {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
sb.append(gson.toJson(fdocs));
}
return sb.toString();
}
private String parseHtmlToMarkdown(String classdoc) {
String markdown = FlexmarkHtmlParser.parse(classdoc);
return markdown;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy