package io.vertx.codegen.type;

import javax.lang.model.element.*;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

Author:
/** * @author <a href="mailto:cafeinoman@openaliasbox.org>Francois Delalleau</a> */
public class AnnotationValueInfoFactory { private final Elements elementUtils; private final TypeMirrorFactory typeFactory; public AnnotationValueInfoFactory(TypeMirrorFactory typeMirrorFactory) { this.elementUtils = typeMirrorFactory.elementUtils; this.typeFactory = typeMirrorFactory; } public AnnotationValueInfo processAnnotation(AnnotationMirror annotation) { String fqn = ((TypeElement) annotation.getAnnotationType().asElement()).getQualifiedName().toString(); AnnotationValueInfo owner = new AnnotationValueInfo(fqn); Map<? extends ExecutableElement, ? extends AnnotationValue> valueMap = elementUtils.getElementValuesWithDefaults(annotation); for (ExecutableElement valueElt : valueMap.keySet().stream().filter(e -> e.getKind().equals(ElementKind.METHOD)).collect(Collectors.toSet())) { owner.putMember(valueElt.getSimpleName().toString(), processAnnotationMemberValue(valueMap.get(valueElt))); } return owner; } @SuppressWarnings("unchecked") private Object processAnnotationMemberValue(AnnotationValue value) { Object realValue = value.getValue(); if (realValue instanceof VariableElement) { realValue = ((VariableElement) realValue).getSimpleName().toString(); } else if (realValue instanceof AnnotationMirror) { realValue = processAnnotation((AnnotationMirror) realValue); } else if (realValue instanceof TypeMirror) { realValue = typeFactory.create((TypeMirror) realValue); } else if (realValue instanceof List) { realValue = ((List<AnnotationValue>) realValue).stream().map(AnnotationValue::getValue).collect(Collectors.toList()); if (((List) realValue).isEmpty()) { realValue = Collections.emptyList(); } else if (((List) realValue).get(0) instanceof AnnotationMirror) { realValue = ((List<AnnotationMirror>) realValue).stream().map(this::processAnnotation).collect(Collectors.toList()); } else if (((List) realValue).get(0) instanceof TypeMirror) { realValue = ((List<TypeMirror>) realValue).stream().map(typeFactory::create).collect(Collectors.toList()); } else if (((List) realValue).get(0) instanceof VariableElement) { realValue = ((List<VariableElement>) realValue).stream().map(v -> v.getSimpleName().toString()).collect(Collectors.toList()); } } return realValue; } }