All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.virtdata.processors.InlineDocData Maven / Gradle / Ivy

package io.virtdata.processors;

import com.squareup.javapoet.*;
import org.yaml.snakeyaml.Yaml;

import javax.annotation.processing.Filer;
import javax.annotation.processing.Messager;
import javax.lang.model.element.Modifier;
import javax.tools.Diagnostic;
import javax.tools.FileObject;
import javax.tools.JavaFileObject;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class InlineDocData implements DocsEnumerator.Listener {

    private final String suffix;
    Yaml yamlAPI = new Yaml();
    private Filer filer;
    private Messager messenger;
    private String anchorPackage;
    private String anchorElement;
    private List docs = new ArrayList<>();
    private Writer writer;

    public InlineDocData(Filer filer, Messager messenger, String suffix) {
        this.filer = filer;
        this.messenger = messenger;
        this.suffix = suffix;
    }

    @Override
    public void onAnchorModel(String packageName, String anchorName) {
        this.anchorPackage = packageName;
        this.anchorElement = anchorName;
    }

    @Override
    public void onFunctionModel(DocForFunc functionDoc) {
        docs.add(functionDoc);
    }

    @Override
    public void onComplete() {

        MethodSpec.Builder methodSpec = MethodSpec.methodBuilder("getDocsInfo")
                .addModifiers(Modifier.PUBLIC)
                .returns(ParameterizedTypeName.get(List.class, DocFuncData.class));

        CodeBlock preamble = CodeBlock.builder()
                .addStatement("$T<$T> docFuncData = new $T<$T>();", List.class, DocFuncData.class, ArrayList.class, DocFuncData.class)
                .build();

        CodeBlock.Builder bigmethod = CodeBlock.builder().add(preamble);

        //        .addStatement(preamble).addStatement("$>");

        for (DocForFunc doc : docs) {
            bigmethod.add("docFuncData.add(\n$>new $T(){{\n$>", DocForFunc.class);
            bigmethod.addStatement("setClassName($S)", doc.getClassName());
            bigmethod.addStatement("setPackageName($S)", doc.getPackageName());
            bigmethod.addStatement("setClassJavadoc($S)", doc.getClassJavadoc());
            bigmethod.addStatement("setInType($S)", doc.getInType());
            bigmethod.addStatement("setOutType($S)", doc.getOutType());
            for (DocCtorData ctor : doc.getCtors()) {
                bigmethod.add("addCtor($S,\n$>",ctor.getCtorJavaDoc());
                bigmethod.add("new $T() {{\n$>", LinkedHashMap.class);
                for (Map.Entry arg : ctor.getArgs().entrySet()) {
                    bigmethod.add("put($S,$S);\n", arg.getKey(), arg.getValue());
                }
                bigmethod.add("$<}},\n");
                bigmethod.add("new $T<$T<$T>>() {{$>\n", ArrayList.class, List.class,String.class);
                for (List examples : ctor.getExamples()) {
                    bigmethod.add("add(new $T<$T>() {{$>\n", ArrayList.class, String.class);
                    for (String example : examples) {
                        bigmethod.add("add($S);\n",example);
                    }
                    bigmethod.add("$<}});\n");
                }
                bigmethod.add("$<}}\n$<);\n");
            }
            bigmethod.add("$<}}\n$<);\n");

        }
        bigmethod.add("return docFuncData;\n");
        CodeBlock bigCodeBlock = bigmethod.build();
        MethodSpec bigMethod = methodSpec.addCode(bigCodeBlock).build();

        TypeSpec manifestType = TypeSpec.classBuilder(anchorElement + suffix)
                .addModifiers(Modifier.PUBLIC)
                .addMethod(bigMethod)
                .addSuperinterface(VirtDataLibraryInfo.class)
                .build();

        JavaFile javafile = JavaFile.builder(this.anchorPackage, manifestType)
                .addFileComment("This file is auto-generated.")
                .build();

        try {
            javafile.writeTo(this.filer);
        } catch (IOException e) {
            messenger.printMessage(Diagnostic.Kind.ERROR, "Error writing javafile " + anchorElement + suffix + " in package " + this.anchorPackage);
            throw new RuntimeException(e);
        }

    }


    private TypeSpec createInlineClassForDocFuncData(DocForFunc doc) {
        List methods = new ArrayList<>();

        MethodSpec getClassName = MethodSpec.methodBuilder("getClassName")
                .addModifiers(Modifier.PUBLIC)
                .returns(String.class)
                .addStatement("return $S", doc.getClassName())
                .build();
        methods.add(getClassName);

        MethodSpec getPackageName = MethodSpec.methodBuilder("getPackageName")
                .addModifiers(Modifier.PUBLIC)
                .returns(String.class)
                .addStatement("return $S", doc.getPackageName())
                .build();

        methods.add(getPackageName);

        MethodSpec getClassJavaDoc = MethodSpec.methodBuilder("getClassJavaDoc")
                .addModifiers(Modifier.PUBLIC)
                .returns(String.class)
                .addStatement("return $S", doc.getClassJavadoc())
                .build();
        methods.add(getClassJavaDoc);

        MethodSpec getInType = MethodSpec.methodBuilder("getInType")
                .addModifiers(Modifier.PUBLIC)
                .returns(String.class)
                .addStatement("return $S", doc.getInType())
                .build();
        methods.add(getInType);

        MethodSpec getOutType = MethodSpec.methodBuilder("getOutType")
                .addModifiers(Modifier.PUBLIC)
                .returns(String.class)
                .addStatement("return $S", doc.getOutType())
                .build();
        methods.add(getOutType);

        CodeBlock ctorsHead = CodeBlock.builder().add("return new $T<$T>() {{$>\n", ArrayList.class, DocForFuncCtor.class).build();
        CodeBlock ctorsTail = CodeBlock.builder().add("$<};").build();

        CodeBlock.Builder ctors = CodeBlock.builder().add(ctorsHead);
        for (DocCtorData ctor : doc.getCtors()) {
            ctors.add("add(new DocForFuncCtor($S, $S, \n$>new $T() {{\n$>", ctor.getClassName(), ctor.getCtorJavaDoc(), LinkedHashMap.class);
            for (Map.Entry arg : ctor.getArgs().entrySet()) {
                ctors.add("put($S,$S);\n", arg.getKey(), arg.getValue());
            }
            ctors.add("$<}}\n$<));\n");
        }
        ctors.add(ctorsTail);

        MethodSpec getCtors = MethodSpec.methodBuilder("getCtors")
                .addModifiers(Modifier.PUBLIC)
                .returns(List.class)
                .addStatement(ctors.build())
                .build();
        methods.add(getCtors);

        TypeSpec inlineSpec = TypeSpec.classBuilder(this.anchorElement + suffix)
                .addMethods(methods)
                .build();

        return inlineSpec;
    }

    private Writer getWriter() {
        if (writer == null) {
            try {
                FileObject resource;
                String docDataFilename = anchorPackage + "." + anchorElement + suffix;
                messenger.printMessage(Diagnostic.Kind.NOTE, "writing docs manifest to " + docDataFilename);
                JavaFileObject sourceFile = filer.createSourceFile(anchorPackage + "." + anchorElement + "DocData");

            } catch (IOException e) {
                messenger.printMessage(Diagnostic.Kind.ERROR, e.toString());
            }
        }
        return writer;
    }
}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy