Search in sources :

Example 11 with BeanInfo

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));
            }
        }
    }
}
Also used : Type(org.jboss.jandex.Type) BeanInfo(io.quarkus.arc.processor.BeanInfo) RegisterForReflection(io.quarkus.runtime.annotations.RegisterForReflection) DotName(org.jboss.jandex.DotName) AnnotationInstance(org.jboss.jandex.AnnotationInstance) ClassInfo(org.jboss.jandex.ClassInfo) BuildStep(io.quarkus.deployment.annotations.BuildStep)

Example 12 with BeanInfo

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;
        }
    });
}
Also used : ClassOutput(io.quarkus.gizmo.ClassOutput) BeanInfo(io.quarkus.arc.processor.BeanInfo) BeanInfo(io.quarkus.arc.processor.BeanInfo)

Example 13 with BeanInfo

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);
    }
}
Also used : BeanInfo(io.quarkus.arc.processor.BeanInfo) ArrayList(java.util.ArrayList) MethodInfo(org.jboss.jandex.MethodInfo) AnnotationInstance(org.jboss.jandex.AnnotationInstance) BuildStep(io.quarkus.deployment.annotations.BuildStep)

Example 14 with BeanInfo

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('/', '.');
}
Also used : ArcContainer(io.quarkus.arc.ArcContainer) BeanInfo(io.quarkus.arc.processor.BeanInfo) DefaultInvoker(io.quarkus.scheduler.common.runtime.DefaultInvoker) TryBlock(io.quarkus.gizmo.TryBlock) ClassCreator(io.quarkus.gizmo.ClassCreator) Type(org.jboss.jandex.Type) CompletableFuture(java.util.concurrent.CompletableFuture) Arc(io.quarkus.arc.Arc) MethodCreator(io.quarkus.gizmo.MethodCreator) InjectableBean(io.quarkus.arc.InjectableBean) ScheduledExecution(io.quarkus.scheduler.ScheduledExecution) MethodInfo(org.jboss.jandex.MethodInfo) ResultHandle(io.quarkus.gizmo.ResultHandle) CatchBlockCreator(io.quarkus.gizmo.CatchBlockCreator) InstanceHandle(io.quarkus.arc.InstanceHandle) ClassInfo(org.jboss.jandex.ClassInfo)

Example 15 with BeanInfo

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;
}
Also used : Arrays(java.util.Arrays) DotName(org.jboss.jandex.DotName) ClassInfo(org.jboss.jandex.ClassInfo) CombinedIndexBuildItem(io.quarkus.deployment.builditem.CombinedIndexBuildItem) BuildProducer(io.quarkus.deployment.annotations.BuildProducer) ArrayList(java.util.ArrayList) MethodInfo(org.jboss.jandex.MethodInfo) AnnotationTarget(org.jboss.jandex.AnnotationTarget) NoSuchElementException(java.util.NoSuchElementException) ConnectorBuildItem(io.quarkus.smallrye.reactivemessaging.deployment.items.ConnectorBuildItem) AnnotationValue(org.jboss.jandex.AnnotationValue) Opcodes(org.objectweb.asm.Opcodes) ConnectorAttribute(io.smallrye.reactive.messaging.annotations.ConnectorAttribute) Collection(java.util.Collection) TransformedAnnotationsBuildItem(io.quarkus.arc.deployment.TransformedAnnotationsBuildItem) InjectionPointInfo(io.quarkus.arc.processor.InjectionPointInfo) Collectors(java.util.stream.Collectors) List(java.util.List) ConfigProvider(org.eclipse.microprofile.config.ConfigProvider) AnnotationInstance(org.jboss.jandex.AnnotationInstance) ChannelDirection(io.quarkus.smallrye.reactivemessaging.deployment.items.ChannelDirection) Optional(java.util.Optional) ChannelBuildItem(io.quarkus.smallrye.reactivemessaging.deployment.items.ChannelBuildItem) Collections(java.util.Collections) BeanInfo(io.quarkus.arc.processor.BeanInfo) ConnectorAttribute(io.smallrye.reactive.messaging.annotations.ConnectorAttribute) ArrayList(java.util.ArrayList) AnnotationInstance(org.jboss.jandex.AnnotationInstance)

Aggregations

BeanInfo (io.quarkus.arc.processor.BeanInfo)16 BuildStep (io.quarkus.deployment.annotations.BuildStep)12 AnnotationInstance (org.jboss.jandex.AnnotationInstance)8 MethodInfo (org.jboss.jandex.MethodInfo)7 ClassInfo (org.jboss.jandex.ClassInfo)5 Type (org.jboss.jandex.Type)4 ArrayList (java.util.ArrayList)3 Predicate (java.util.function.Predicate)3 AnnotationStore (io.quarkus.arc.processor.AnnotationStore)2 DecoratorInfo (io.quarkus.arc.processor.DecoratorInfo)2 InjectionPointInfo (io.quarkus.arc.processor.InjectionPointInfo)2 InterceptorInfo (io.quarkus.arc.processor.InterceptorInfo)2 BuildProducer (io.quarkus.deployment.annotations.BuildProducer)2 Record (io.quarkus.deployment.annotations.Record)2 ClassOutput (io.quarkus.gizmo.ClassOutput)2 ResultHandle (io.quarkus.gizmo.ResultHandle)2 MediatorBuildItem (io.quarkus.smallrye.reactivemessaging.deployment.items.MediatorBuildItem)2 HashSet (java.util.HashSet)2 Set (java.util.Set)2 DeploymentException (javax.enterprise.inject.spi.DeploymentException)2