use of io.micronaut.annotation.processing.visitor.JavaVisitorContext in project micronaut-kubernetes by micronaut-projects.
the class KubernetesApisProcessor method writeReactorClients.
private void writeReactorClients(Element e, String packageName, String simpleName) {
final String reactorClientName = simpleName + "ReactorClient";
final String reactorPackageName = packageName.replace(KUBERNETES_APIS_PACKAGE, MICRONAUT_APIS_PACKAGE + ".reactor");
ClassName cn = ClassName.get(reactorPackageName, reactorClientName);
TypeSpec.Builder builder = TypeSpec.classBuilder(cn);
ClassName clientType = ClassName.get(packageName, simpleName);
ClassName reactorMonoType = ClassName.get("reactor.core.publisher", "Mono");
final AnnotationSpec.Builder requiresSpec = AnnotationSpec.builder(Requires.class).addMember("beans", "{$T.class}", clientType);
builder.addAnnotation(requiresSpec.build());
builder.addAnnotation(Singleton.class);
if (Objects.equals(simpleName, "CoreV1Api")) {
builder.addAnnotation(BootstrapContextCompatible.class);
}
builder.addModifiers(Modifier.PUBLIC);
builder.addField(clientType, "client", Modifier.FINAL, Modifier.PRIVATE);
builder.addMethod(MethodSpec.constructorBuilder().addParameter(clientType, "client").addCode("this.client = client;").build());
TypeElement typeElement = elements.getTypeElement(clientType.reflectionName());
if (typeElement != null) {
ModelUtils modelUtils = new ModelUtils(elements, types) {
};
GenericUtils genericUtils = new GenericUtils(elements, types, modelUtils) {
};
AnnotationUtils annotationUtils = new AnnotationUtils(processingEnv, elements, messager, types, modelUtils, genericUtils, filer) {
};
JavaVisitorContext visitorContext = new JavaVisitorContext(processingEnv, messager, elements, annotationUtils, types, modelUtils, genericUtils, filer, MutableConvertibleValues.of(new LinkedHashMap<>()), TypeElementVisitor.VisitorKind.ISOLATING);
typeElement.asType().accept(new PublicMethodVisitor<Object, Object>(visitorContext) {
@Override
protected void accept(DeclaredType type, Element element, Object o) {
ExecutableElement ee = (ExecutableElement) element;
TypeMirror returnType = ee.getReturnType();
if (element.getSimpleName().toString().endsWith("Async")) {
DeclaredType dt = (DeclaredType) returnType;
Element e = dt.asElement();
if (e.getSimpleName().toString().equals("Call")) {
List<? extends VariableElement> parameters = ee.getParameters();
VariableElement fieldElement = parameters.get(parameters.size() - 1);
TypeMirror typeMirror = fieldElement.asType();
if (typeMirror instanceof DeclaredType) {
DeclaredType cdt = (DeclaredType) typeMirror;
List<? extends TypeMirror> typeArguments = cdt.getTypeArguments();
if (typeArguments.size() == 1) {
TypeMirror ctm = typeArguments.get(0);
if (ctm instanceof DeclaredType) {
// resolve the callback response type
TypeName responseType = ClassName.get(ctm);
// resolve the method name by removing the Async suffix
String methodName = ee.getSimpleName().toString();
String finalMethodName = methodName.replace("Async", "");
// prepare parameters for the method without tha _callback one
List<ParameterSpec> parameterSpecs = parameters.stream().filter(va -> !va.getSimpleName().toString().equals("_callback")).filter(va -> !va.getSimpleName().toString().equals("watch")).map(va -> ParameterSpec.builder(ClassName.get(va.asType()), va.getSimpleName().toString()).build()).collect(Collectors.toList());
MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(finalMethodName).addModifiers(Modifier.PUBLIC).addParameters(parameterSpecs).returns(ParameterizedTypeName.get(reactorMonoType, responseType));
methodBuilder.addCode(CodeBlock.builder().addStatement("return $T.create((sink) -> {", reactorMonoType).addStatement("try {").add(" this.client." + methodName + "(").add(parameters.stream().map(va -> {
String name = va.getSimpleName().toString();
if (name.equals("_callback")) {
return "new AsyncCallbackSink<" + responseType + ">(sink)";
} else if (name.equals("watch")) {
return "Boolean.FALSE";
} else {
return name;
}
}).collect(Collectors.joining(", "))).addStatement(")").addStatement("} catch(io.kubernetes.client.openapi.ApiException e) { sink.error(e); }").addStatement("})").build());
builder.addMethod(methodBuilder.build());
}
}
}
}
}
}
}, null);
}
writeJavaFile(e, reactorPackageName, cn, builder);
}
use of io.micronaut.annotation.processing.visitor.JavaVisitorContext in project odi by eclipse-ee4j.
the class AnnotatedConstructAnnotationTarget method asClassElement.
private ClassElement asClassElement(DeclaredType declaredType) {
javax.lang.model.element.Element annotationElement = declaredType.asElement();
JavaVisitorContext javaVisitorContext = visitorContext;
ClassElement classElement = javaVisitorContext.getElementFactory().newClassElement((TypeElement) declaredType.asElement(), visitorContext.getAnnotationUtils().getAnnotationMetadata(annotationElement));
return classElement;
}
use of io.micronaut.annotation.processing.visitor.JavaVisitorContext in project micronaut-core by micronaut-projects.
the class BeanDefinitionInjectProcessor method process.
@Override
public final boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
processingOver = roundEnv.processingOver();
if (!processingOver) {
annotations = annotations.stream().filter(ann -> {
final String name = ann.getQualifiedName().toString();
String packageName = NameUtils.getPackageName(name);
return !name.equals(AnnotationUtil.KOTLIN_METADATA) && !AnnotationUtil.STEREOTYPE_EXCLUDES.contains(packageName);
}).filter(ann -> annotationUtils.hasStereotype(ann, ANNOTATION_STEREOTYPES) || isProcessedAnnotation(ann.getQualifiedName().toString())).collect(Collectors.toSet());
if (!annotations.isEmpty()) {
TypeElement groovyObjectTypeElement = elementUtils.getTypeElement("groovy.lang.GroovyObject");
TypeMirror groovyObjectType = groovyObjectTypeElement != null ? groovyObjectTypeElement.asType() : null;
// accumulate all the class elements for all annotated elements
annotations.forEach(annotation -> roundEnv.getElementsAnnotatedWith(annotation).stream().filter(element -> element.getKind() != ANNOTATION_TYPE).forEach(element -> {
TypeElement typeElement = modelUtils.classElementFor(element);
if (typeElement == null) {
return;
}
if (element.getKind() == ENUM) {
final AnnotationMetadata am = annotationUtils.getAnnotationMetadata(element);
if (isDeclaredBeanInMetadata(am)) {
error(element, "Enum types cannot be defined as beans");
}
return;
}
// skip Groovy code, handled by InjectTransform. Required for GroovyEclipse compiler
if ((groovyObjectType != null && typeUtils.isAssignable(typeElement.asType(), groovyObjectType))) {
return;
}
String name = typeElement.getQualifiedName().toString();
if (!beanDefinitions.contains(name) && !processed.contains(name) && !name.endsWith(BeanDefinitionVisitor.PROXY_SUFFIX)) {
boolean isInterface = JavaModelUtils.resolveKind(typeElement, ElementKind.INTERFACE).isPresent();
if (!isInterface) {
beanDefinitions.add(name);
} else {
if (annotationUtils.hasStereotype(typeElement, INTRODUCTION_TYPE) || annotationUtils.hasStereotype(typeElement, ConfigurationReader.class)) {
beanDefinitions.add(name);
}
}
}
}));
}
// remove already processed in previous round
for (String name : processed) {
beanDefinitions.remove(name);
}
// process remaining
int count = beanDefinitions.size();
if (count > 0) {
note("Creating bean classes for %s type elements", count);
beanDefinitions.forEach(className -> {
if (processed.add(className)) {
final TypeElement refreshedClassElement = elementUtils.getTypeElement(className);
try {
final AnnBeanElementVisitor visitor = new AnnBeanElementVisitor(refreshedClassElement);
refreshedClassElement.accept(visitor, className);
visitor.getBeanDefinitionWriters().forEach((name, writer) -> {
String beanDefinitionName = writer.getBeanDefinitionName();
if (processed.add(beanDefinitionName)) {
processBeanDefinitions(writer);
}
});
AnnotationUtils.invalidateMetadata(refreshedClassElement);
} catch (PostponeToNextRoundException e) {
processed.remove(className);
}
}
});
AnnotationUtils.invalidateCache();
}
}
/*
Since the underlying Filer expects us to write only once into a file we need to make sure it happens in the last
processing round.
*/
if (processingOver) {
try {
writeBeanDefinitionsToMetaInf();
for (BeanElementVisitor<?> visitor : BeanElementVisitor.VISITORS) {
if (visitor.isEnabled()) {
try {
visitor.finish(javaVisitorContext);
} catch (Exception e) {
javaVisitorContext.fail("Error finalizing bean element visitor [" + visitor.getClass().getName() + "]: " + e.getMessage(), null);
}
}
}
final List<AbstractBeanDefinitionBuilder> beanElementBuilders = javaVisitorContext.getBeanElementBuilders();
if (CollectionUtils.isNotEmpty(beanElementBuilders)) {
try {
AbstractBeanDefinitionBuilder.writeBeanDefinitionBuilders(classWriterOutputVisitor, beanElementBuilders);
} catch (IOException e) {
// raise a compile error
String message = e.getMessage();
error("Unexpected error: %s", message != null ? message : e.getClass().getSimpleName());
}
}
} finally {
AnnotationUtils.invalidateCache();
AbstractAnnotationMetadataBuilder.clearMutated();
JavaAnnotationMetadataBuilder.clearCaches();
}
}
return false;
}
use of io.micronaut.annotation.processing.visitor.JavaVisitorContext in project micronaut-kubernetes by micronaut-projects.
the class KubernetesApisProcessor method writeRxJavaClients.
private void writeRxJavaClients(Element e, String packageName, String simpleName, String rxVersionSuffix, String rxJavaPackage) {
final String rx = simpleName + "RxClient";
final String rxPackageName = packageName.replace(KUBERNETES_APIS_PACKAGE, MICRONAUT_APIS_PACKAGE + rxVersionSuffix);
ClassName cn = ClassName.get(rxPackageName, rx);
TypeSpec.Builder builder = TypeSpec.classBuilder(cn);
ClassName clientType = ClassName.get(packageName, simpleName);
ClassName rxSingleType = ClassName.get(rxJavaPackage, "Single");
final AnnotationSpec.Builder requiresSpec = AnnotationSpec.builder(Requires.class).addMember("beans", "{$T.class}", clientType);
builder.addAnnotation(requiresSpec.build());
builder.addAnnotation(Singleton.class);
builder.addModifiers(Modifier.PUBLIC);
builder.addField(clientType, "client", Modifier.FINAL, Modifier.PRIVATE);
builder.addMethod(MethodSpec.constructorBuilder().addParameter(clientType, "client").addCode("this.client = client;").build());
TypeElement typeElement = elements.getTypeElement(clientType.reflectionName());
if (typeElement != null) {
ModelUtils modelUtils = new ModelUtils(elements, types) {
};
GenericUtils genericUtils = new GenericUtils(elements, types, modelUtils) {
};
AnnotationUtils annotationUtils = new AnnotationUtils(processingEnv, elements, messager, types, modelUtils, genericUtils, filer) {
};
JavaVisitorContext visitorContext = new JavaVisitorContext(processingEnv, messager, elements, annotationUtils, types, modelUtils, genericUtils, filer, MutableConvertibleValues.of(new LinkedHashMap<>()), TypeElementVisitor.VisitorKind.ISOLATING);
typeElement.asType().accept(new PublicMethodVisitor<Object, Object>(visitorContext) {
@Override
protected void accept(DeclaredType type, Element element, Object o) {
ExecutableElement ee = (ExecutableElement) element;
TypeMirror returnType = ee.getReturnType();
if (element.getSimpleName().toString().endsWith("Async")) {
DeclaredType dt = (DeclaredType) returnType;
Element e = dt.asElement();
if (e.getSimpleName().toString().equals("Call")) {
List<? extends VariableElement> parameters = ee.getParameters();
VariableElement fieldElement = parameters.get(parameters.size() - 1);
TypeMirror typeMirror = fieldElement.asType();
if (typeMirror instanceof DeclaredType) {
DeclaredType cdt = (DeclaredType) typeMirror;
List<? extends TypeMirror> typeArguments = cdt.getTypeArguments();
if (typeArguments.size() == 1) {
TypeMirror ctm = typeArguments.get(0);
if (ctm instanceof DeclaredType) {
// resolve the callback response type
TypeName responseType = ClassName.get(ctm);
// resolve the method name by removing the Async suffix
String methodName = ee.getSimpleName().toString();
String finalMethodName = methodName.replace("Async", "");
// prepare parameters for the method without tha _callback one
List<ParameterSpec> parameterSpecs = parameters.stream().filter(va -> !va.getSimpleName().toString().equals("_callback")).filter(va -> !va.getSimpleName().toString().equals("watch")).map(va -> ParameterSpec.builder(ClassName.get(va.asType()), va.getSimpleName().toString()).build()).collect(Collectors.toList());
MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(finalMethodName).addModifiers(Modifier.PUBLIC).addParameters(parameterSpecs).returns(ParameterizedTypeName.get(rxSingleType, responseType));
methodBuilder.addCode(CodeBlock.builder().addStatement("return $T.create((emitter) -> {", rxSingleType).add("this.client." + methodName + "(").add(parameters.stream().map(va -> {
String name = va.getSimpleName().toString();
if (name.equals("_callback")) {
return "new ApiCallbackEmitter<>(emitter)";
} else if (name.equals("watch")) {
return "Boolean.FALSE";
} else {
return name;
}
}).collect(Collectors.joining(", "))).addStatement(")").addStatement("})").build());
builder.addMethod(methodBuilder.build());
}
}
}
}
}
}
}, null);
}
writeJavaFile(e, rxPackageName, cn, builder);
}
Aggregations