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

com.github.therapi.runtimejavadoc.internal.JsonJavadocBuilder Maven / Gradle / Ivy

package com.github.therapi.runtimejavadoc.internal;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Types;

import com.eclipsesource.json.Json;
import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
import com.eclipsesource.json.JsonValue;

import static com.github.therapi.runtimejavadoc.internal.RuntimeJavadocHelper.elementDocFieldName;
import static com.github.therapi.runtimejavadoc.internal.RuntimeJavadocHelper.elementNameFieldName;
import static com.github.therapi.runtimejavadoc.internal.RuntimeJavadocHelper.enumConstantsFieldName;
import static com.github.therapi.runtimejavadoc.internal.RuntimeJavadocHelper.fieldsFieldName;
import static com.github.therapi.runtimejavadoc.internal.RuntimeJavadocHelper.methodsFieldName;
import static com.github.therapi.runtimejavadoc.internal.RuntimeJavadocHelper.paramTypesFieldName;

class JsonJavadocBuilder {

    private static final Collector JSON_ARRAY_COLLECTOR = Collector.of(JsonArray::new,
            JsonArray::add, (arr1, arr2) -> {
                arr2.forEach(arr1::add);
                return arr1;
            });

    private final ProcessingEnvironment processingEnv;

    JsonJavadocBuilder(ProcessingEnvironment processingEnv) {
        this.processingEnv = processingEnv;
    }

    Optional getClassJavadocAsJson(TypeElement classElement) {
        String classDoc = processingEnv.getElementUtils().getDocComment(classElement);

        if (isBlank(classDoc)) {
            classDoc = "";
        }

        Map> children = classElement.getEnclosedElements()
                                                               .stream()
                                                               .collect(Collectors.groupingBy(Element::getKind));
        List enclosedFields = children.getOrDefault(ElementKind.FIELD, Collections.emptyList());
        List enclosedEnumConstants = children.getOrDefault(ElementKind.ENUM_CONSTANT, Collections.emptyList());
        List enclosedMethods = children.getOrDefault(ElementKind.METHOD, Collections.emptyList());

        JsonArray fieldDocs = getJavadocsAsJson(enclosedFields, this::getFieldJavadocAsJson);
        JsonArray enumConstantDocs = getJavadocsAsJson(enclosedEnumConstants, this::getFieldJavadocAsJson);
        JsonArray methodDocs = getJavadocsAsJson(enclosedMethods, this::getMethodJavadocAsJson);

        if (isBlank(classDoc) && fieldDocs.isEmpty() && enumConstantDocs.isEmpty() && methodDocs.isEmpty()) {
            return Optional.empty();
        }

        JsonObject json = new JsonObject();
        json.add(elementDocFieldName(), classDoc);
        json.add(fieldsFieldName(), fieldDocs);
        json.add(enumConstantsFieldName(), enumConstantDocs);
        json.add(methodsFieldName(), methodDocs);
        return Optional.of(json);
    }

    private static JsonArray getJavadocsAsJson(List elements,
            Function> createDoc) {
        return elements.stream()
                       .map(createDoc)
                       .filter(Optional::isPresent)
                       .map(Optional::get)
                       .collect(JSON_ARRAY_COLLECTOR);
    }

    private Optional getFieldJavadocAsJson(Element field) {
        String javadoc = processingEnv.getElementUtils().getDocComment(field);
        if (isBlank(javadoc)) {
            return Optional.empty();
        }

        JsonObject jsonDoc = new JsonObject();
        jsonDoc.add(elementNameFieldName(), field.getSimpleName().toString());
        jsonDoc.add(elementDocFieldName(), javadoc);
        return Optional.of(jsonDoc);
    }

    private Optional getMethodJavadocAsJson(Element method) {
        assert method instanceof ExecutableElement;

        String methodJavadoc = processingEnv.getElementUtils().getDocComment(method);
        if (isBlank(methodJavadoc)) {
            return Optional.empty();
        }

        JsonObject jsonDoc = new JsonObject();
        jsonDoc.add(elementNameFieldName(), method.getSimpleName().toString());
        jsonDoc.add(paramTypesFieldName(), getParamErasures((ExecutableElement) method));
        jsonDoc.add(elementDocFieldName(), methodJavadoc);
        return Optional.of(jsonDoc);
    }

    private JsonArray getParamErasures(ExecutableElement executableElement) {
        Types typeUtils = processingEnv.getTypeUtils();
        return executableElement.getParameters()
                                .stream()
                                .map(Element::asType)
                                .map(typeUtils::erasure)
                                .map(TypeMirror::toString)
                                .map(Json::value)
                                .collect(JSON_ARRAY_COLLECTOR);
    }

    private static boolean isBlank(String s) {
        return s == null || s.trim().isEmpty();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy