use of io.quarkus.arc.processor.BeanInfo in project quarkus by quarkusio.
the class ReflectiveBeanClassesProcessor method implicitReflectiveBeanClasses.
@BuildStep
void implicitReflectiveBeanClasses(BuildProducer<ReflectiveBeanClassBuildItem> reflectiveBeanClasses, BeanDiscoveryFinishedBuildItem beanDiscoveryFinished) {
DotName registerForReflection = DotName.createSimple(RegisterForReflection.class.getName());
for (BeanInfo classBean : beanDiscoveryFinished.beanStream().classBeans()) {
ClassInfo beanClass = classBean.getTarget().get().asClass();
AnnotationInstance annotation = beanClass.classAnnotation(registerForReflection);
if (annotation != null) {
Type[] targets = annotation.value("targets") != null ? annotation.value("targets").asClassArray() : new Type[] {};
String[] classNames = annotation.value("classNames") != null ? annotation.value("classNames").asStringArray() : new String[] {};
if (targets.length == 0 && classNames.length == 0) {
reflectiveBeanClasses.produce(new ReflectiveBeanClassBuildItem(beanClass));
}
}
}
}
use of io.quarkus.arc.processor.BeanInfo in project quarkus by quarkusio.
the class MicroprofileMetricsProcessor method processAnnotatedMetrics.
@BuildStep(onlyIf = MicroprofileMetricsEnabled.class)
UnremovableBeanBuildItem processAnnotatedMetrics(BuildProducer<GeneratedBeanBuildItem> generatedBeans, BuildProducer<AnnotationsTransformerBuildItem> annotationsTransformers, CombinedIndexBuildItem indexBuildItem) {
IndexView index = indexBuildItem.getIndex();
ClassOutput classOutput = new GeneratedBeanGizmoAdaptor(generatedBeans);
// Gauges.
GaugeAnnotationHandler.processAnnotatedGauges(index, classOutput);
annotationsTransformers.produce(AnnotationHandler.transformAnnotations(index, MetricDotNames.CONCURRENT_GAUGE_ANNOTATION));
// Invocation counters
annotationsTransformers.produce(AnnotationHandler.transformAnnotations(index, MetricDotNames.COUNTED_ANNOTATION));
annotationsTransformers.produce(AnnotationHandler.transformAnnotations(index, MetricDotNames.METERED_ANNOTATION, MetricDotNames.COUNTED_ANNOTATION));
// Timed annotations. SimplyTimed --> Timed
annotationsTransformers.produce(AnnotationHandler.transformAnnotations(index, MetricDotNames.TIMED_ANNOTATION));
annotationsTransformers.produce(AnnotationHandler.transformAnnotations(index, MetricDotNames.SIMPLY_TIMED_ANNOTATION, MetricDotNames.TIMED_ANNOTATION));
// @Metric
annotationsTransformers.produce(AnnotationHandler.transformAnnotations(index, MetricDotNames.METRIC_ANNOTATION));
return new UnremovableBeanBuildItem(new Predicate<BeanInfo>() {
@Override
public boolean test(io.quarkus.arc.processor.BeanInfo beanInfo) {
if (beanInfo.hasType(MetricDotNames.METRIC) || beanInfo.hasType(MetricDotNames.ANNOTATED_GAUGE_ADAPTER)) {
return true;
}
return false;
}
});
}
use of io.quarkus.arc.processor.BeanInfo in project quarkus by quarkusio.
the class SchedulerProcessor method collectScheduledMethods.
@BuildStep
void collectScheduledMethods(BeanArchiveIndexBuildItem beanArchives, BeanDiscoveryFinishedBuildItem beanDiscovery, TransformedAnnotationsBuildItem transformedAnnotations, BuildProducer<ScheduledBusinessMethodItem> scheduledBusinessMethods) {
// First collect static scheduled methods
List<AnnotationInstance> schedules = new ArrayList<>(beanArchives.getIndex().getAnnotations(SchedulerDotNames.SCHEDULED_NAME));
for (AnnotationInstance annotationInstance : beanArchives.getIndex().getAnnotations(SchedulerDotNames.SCHEDULES_NAME)) {
for (AnnotationInstance scheduledInstance : annotationInstance.value().asNestedArray()) {
// We need to set the target of the containing instance
schedules.add(AnnotationInstance.create(scheduledInstance.name(), annotationInstance.target(), scheduledInstance.values()));
}
}
for (AnnotationInstance annotationInstance : schedules) {
if (annotationInstance.target().kind() != METHOD) {
continue;
}
MethodInfo method = annotationInstance.target().asMethod();
if (Modifier.isStatic(method.flags()) && !KotlinUtil.isSuspendMethod(method)) {
scheduledBusinessMethods.produce(new ScheduledBusinessMethodItem(null, method, schedules, transformedAnnotations.getAnnotation(method, SchedulerDotNames.NON_BLOCKING) != null));
LOGGER.debugf("Found scheduled static method %s declared on %s", method, method.declaringClass().name());
}
}
// Then collect all business methods annotated with @Scheduled
for (BeanInfo bean : beanDiscovery.beanStream().classBeans()) {
collectScheduledMethods(beanArchives.getIndex(), transformedAnnotations, bean, bean.getTarget().get().asClass(), scheduledBusinessMethods);
}
}
use of io.quarkus.arc.processor.BeanInfo in project quarkus by quarkusio.
the class SchedulerProcessor method generateInvoker.
private String generateInvoker(ScheduledBusinessMethodItem scheduledMethod, ClassOutput classOutput) {
BeanInfo bean = scheduledMethod.getBean();
MethodInfo method = scheduledMethod.getMethod();
boolean isStatic = Modifier.isStatic(method.flags());
ClassInfo implClazz = isStatic ? method.declaringClass() : bean.getImplClazz();
String baseName;
if (implClazz.enclosingClass() != null) {
baseName = DotNames.simpleName(implClazz.enclosingClass()) + NESTED_SEPARATOR + DotNames.simpleName(implClazz);
} else {
baseName = DotNames.simpleName(implClazz.name());
}
StringBuilder sigBuilder = new StringBuilder();
sigBuilder.append(method.name()).append("_").append(method.returnType().name().toString());
for (Type i : method.parameters()) {
sigBuilder.append(i.name().toString());
}
String generatedName = DotNames.internalPackageNameWithTrailingSlash(implClazz.name()) + baseName + INVOKER_SUFFIX + "_" + method.name() + "_" + HashUtil.sha1(sigBuilder.toString());
boolean isSuspendMethod = KotlinUtil.isSuspendMethod(method);
ClassCreator invokerCreator = ClassCreator.builder().classOutput(classOutput).className(generatedName).superClass(isSuspendMethod ? SchedulerDotNames.ABSTRACT_COROUTINE_INVOKER.toString() : DefaultInvoker.class.getName()).build();
MethodCreator invoke;
if (isSuspendMethod) {
invoke = invokerCreator.getMethodCreator("invokeBean", Object.class.getName(), ScheduledExecution.class.getName(), SchedulerDotNames.CONTINUATION.toString());
} else {
// The descriptor is: CompletionStage invoke(ScheduledExecution execution)
invoke = invokerCreator.getMethodCreator("invokeBean", CompletionStage.class, ScheduledExecution.class).addException(Exception.class);
}
// Use a try-catch block and return failed future if an exception is thrown
TryBlock tryBlock = invoke.tryBlock();
CatchBlockCreator catchBlock = tryBlock.addCatch(Throwable.class);
if (isSuspendMethod) {
catchBlock.throwException(catchBlock.getCaughtException());
} else {
catchBlock.returnValue(catchBlock.invokeStaticMethod(MethodDescriptor.ofMethod(CompletableFuture.class, "failedStage", CompletionStage.class, Throwable.class), catchBlock.getCaughtException()));
}
String returnTypeStr = DescriptorUtils.typeToString(method.returnType());
ResultHandle res;
if (isStatic) {
if (method.parameters().isEmpty()) {
res = tryBlock.invokeStaticMethod(MethodDescriptor.ofMethod(implClazz.name().toString(), method.name(), returnTypeStr));
} else {
res = tryBlock.invokeStaticMethod(MethodDescriptor.ofMethod(implClazz.name().toString(), method.name(), returnTypeStr, ScheduledExecution.class), tryBlock.getMethodParam(0));
}
} else {
// InjectableBean<Foo> bean = Arc.container().bean("foo1");
// InstanceHandle<Foo> handle = Arc.container().instance(bean);
// handle.get().ping();
ResultHandle containerHandle = tryBlock.invokeStaticMethod(MethodDescriptor.ofMethod(Arc.class, "container", ArcContainer.class));
ResultHandle beanHandle = tryBlock.invokeInterfaceMethod(MethodDescriptor.ofMethod(ArcContainer.class, "bean", InjectableBean.class, String.class), containerHandle, tryBlock.load(bean.getIdentifier()));
ResultHandle instanceHandle = tryBlock.invokeInterfaceMethod(MethodDescriptor.ofMethod(ArcContainer.class, "instance", InstanceHandle.class, InjectableBean.class), containerHandle, beanHandle);
ResultHandle beanInstanceHandle = tryBlock.invokeInterfaceMethod(MethodDescriptor.ofMethod(InstanceHandle.class, "get", Object.class), instanceHandle);
if (isSuspendMethod) {
if (method.parameters().size() == 1) {
res = tryBlock.invokeVirtualMethod(MethodDescriptor.ofMethod(implClazz.name().toString(), method.name(), Object.class.getName(), SchedulerDotNames.CONTINUATION.toString()), beanInstanceHandle, tryBlock.getMethodParam(1));
} else {
res = tryBlock.invokeVirtualMethod(MethodDescriptor.ofMethod(implClazz.name().toString(), method.name(), Object.class.getName(), ScheduledExecution.class.getName(), SchedulerDotNames.CONTINUATION.toString()), beanInstanceHandle, tryBlock.getMethodParam(0), tryBlock.getMethodParam(1));
}
} else {
if (method.parameters().isEmpty()) {
res = tryBlock.invokeVirtualMethod(MethodDescriptor.ofMethod(implClazz.name().toString(), method.name(), returnTypeStr), beanInstanceHandle);
} else {
res = tryBlock.invokeVirtualMethod(MethodDescriptor.ofMethod(implClazz.name().toString(), method.name(), returnTypeStr, ScheduledExecution.class), beanInstanceHandle, tryBlock.getMethodParam(0));
}
}
// handle.destroy() - destroy dependent instance afterwards
if (BuiltinScope.DEPENDENT.is(bean.getScope())) {
tryBlock.invokeInterfaceMethod(MethodDescriptor.ofMethod(InstanceHandle.class, "destroy", void.class), instanceHandle);
}
}
if (res == null) {
// If the return type is void then return a new completed stage
res = tryBlock.invokeStaticMethod(MethodDescriptor.ofMethod(CompletableFuture.class, "completedStage", CompletionStage.class, Object.class), tryBlock.loadNull());
} else if (method.returnType().name().equals(SchedulerDotNames.UNI)) {
// Subscribe to the returned Uni
res = tryBlock.invokeInterfaceMethod(MethodDescriptor.ofMethod(SchedulerDotNames.UNI.toString(), "subscribeAsCompletionStage", CompletableFuture.class), res);
}
tryBlock.returnValue(res);
if (scheduledMethod.isNonBlocking()) {
MethodCreator isBlocking = invokerCreator.getMethodCreator("isBlocking", boolean.class);
isBlocking.returnValue(isBlocking.load(false));
}
invokerCreator.close();
return generatedName.replace('/', '.');
}
use of io.quarkus.arc.processor.BeanInfo in project quarkus by quarkusio.
the class WiringHelper method getConnectorAttributes.
/**
* Collects connector attributes from the given connector implementation.
*
* @param bi the bean implementing the connector interfaces
* @param index the index
* @param directions the attribute direction to includes in the result
* @return the list of connector attributes, empty if none
*/
static List<ConnectorAttribute> getConnectorAttributes(BeanInfo bi, CombinedIndexBuildItem index, ConnectorAttribute.Direction... directions) {
List<AnnotationInstance> attributes = bi.getImplClazz().classAnnotationsWithRepeatable(ReactiveMessagingDotNames.CONNECTOR_ATTRIBUTES, index.getIndex()).stream().flatMap(ai -> Arrays.stream(ai.value().asNestedArray())).collect(Collectors.toList());
if (attributes.isEmpty()) {
AnnotationInstance attribute = bi.getImplClazz().classAnnotation(ReactiveMessagingDotNames.CONNECTOR_ATTRIBUTE);
if (attribute != null) {
attributes = Collections.singletonList(attribute);
}
}
List<ConnectorAttribute> att = new ArrayList<>();
for (AnnotationInstance instance : attributes) {
ConnectorAttribute.Direction direction = ConnectorAttribute.Direction.valueOf(instance.value("direction").asString().toUpperCase());
if (Arrays.asList(directions).contains(direction)) {
ConnectorAttribute literal = createConnectorAttribute(instance, direction);
att.add(literal);
}
}
return att;
}
Aggregations