Search in sources :

Example 1 with AnnotationMetadataHierarchy

use of io.micronaut.inject.annotation.AnnotationMetadataHierarchy in project micronaut-core by micronaut-projects.

the class JavaBeanDefinitionBuilder method createChildBean.

@Override
protected AbstractBeanDefinitionBuilder createChildBean(FieldElement producerField) {
    final ClassElement parentType = getBeanType();
    return new JavaBeanDefinitionBuilder(JavaBeanDefinitionBuilder.this.getOriginatingElement(), producerField.getGenericField().getType(), JavaBeanDefinitionBuilder.this.metadataBuilder, (JavaVisitorContext) JavaBeanDefinitionBuilder.this.visitorContext) {

        @Override
        public Element getProducingElement() {
            return producerField;
        }

        @Override
        public ClassElement getDeclaringElement() {
            return producerField.getDeclaringType();
        }

        @Override
        protected BeanDefinitionWriter createBeanDefinitionWriter() {
            final BeanDefinitionWriter writer = super.createBeanDefinitionWriter();
            final JavaElementFactory elementFactory = ((JavaVisitorContext) visitorContext).getElementFactory();
            final VariableElement variableElement = (VariableElement) producerField.getNativeType();
            writer.visitBeanFactoryField(parentType, elementFactory.newFieldElement(parentType, variableElement, new AnnotationMetadataHierarchy(parentType.getDeclaredMetadata(), producerField.getDeclaredMetadata())));
            return writer;
        }
    };
}
Also used : ClassElement(io.micronaut.inject.ast.ClassElement) VariableElement(javax.lang.model.element.VariableElement) BeanDefinitionWriter(io.micronaut.inject.writer.BeanDefinitionWriter) AnnotationMetadataHierarchy(io.micronaut.inject.annotation.AnnotationMetadataHierarchy)

Example 2 with AnnotationMetadataHierarchy

use of io.micronaut.inject.annotation.AnnotationMetadataHierarchy in project micronaut-core by micronaut-projects.

the class IntrospectedTypeElementVisitor method processIntrospected.

private void processIntrospected(ClassElement element, VisitorContext context, AnnotationValue<Introspected> introspected) {
    final String[] packages = introspected.stringValues("packages");
    final AnnotationClassValue[] classes = introspected.get("classes", AnnotationClassValue[].class, new AnnotationClassValue[0]);
    final boolean metadata = introspected.booleanValue("annotationMetadata").orElse(true);
    final Set<String> includes = CollectionUtils.setOf(introspected.stringValues("includes"));
    final Set<String> excludes = CollectionUtils.setOf(introspected.stringValues("excludes"));
    final Set<String> excludedAnnotations = CollectionUtils.setOf(introspected.stringValues("excludedAnnotations"));
    final Set<String> includedAnnotations = CollectionUtils.setOf(introspected.stringValues("includedAnnotations"));
    final Set<AnnotationValue> indexedAnnotations;
    final Set<AnnotationValue> toIndex = CollectionUtils.setOf(introspected.get("indexed", AnnotationValue[].class, new AnnotationValue[0]));
    Introspected.AccessKind[] accessKinds = introspected.enumValues("accessKind", Introspected.AccessKind.class);
    Introspected.Visibility[] visibilities = introspected.enumValues("visibility", Introspected.Visibility.class);
    if (ArrayUtils.isEmpty(accessKinds)) {
        accessKinds = DEFAULT_ACCESS_KIND;
    }
    if (ArrayUtils.isEmpty(visibilities)) {
        visibilities = DEFAULT_VISIBILITY;
    }
    Introspected.AccessKind[] finalAccessKinds = accessKinds;
    Introspected.Visibility[] finalVisibilities = visibilities;
    if (CollectionUtils.isEmpty(toIndex)) {
        indexedAnnotations = CollectionUtils.setOf(ANN_CONSTRAINT, ANN_VALID);
    } else {
        toIndex.addAll(CollectionUtils.setOf(ANN_CONSTRAINT, ANN_VALID));
        indexedAnnotations = toIndex;
    }
    if (ArrayUtils.isNotEmpty(classes)) {
        AtomicInteger index = new AtomicInteger(0);
        for (AnnotationClassValue aClass : classes) {
            final Optional<ClassElement> classElement = context.getClassElement(aClass.getName());
            classElement.ifPresent(ce -> {
                if (ce.isPublic() && !isIntrospected(context, ce)) {
                    final AnnotationMetadata typeMetadata = ce.getAnnotationMetadata();
                    final AnnotationMetadata resolvedMetadata = typeMetadata == AnnotationMetadata.EMPTY_METADATA ? element.getAnnotationMetadata() : new AnnotationMetadataHierarchy(element.getAnnotationMetadata(), typeMetadata);
                    final BeanIntrospectionWriter writer = new BeanIntrospectionWriter(element.getName(), index.getAndIncrement(), element, ce, metadata ? resolvedMetadata : null);
                    processElement(metadata, includes, excludes, excludedAnnotations, indexedAnnotations, ce, writer, finalVisibilities, finalAccessKinds);
                }
            });
        }
    } else if (ArrayUtils.isNotEmpty(packages)) {
        if (includedAnnotations.isEmpty()) {
            context.fail("When specifying 'packages' you must also specify 'includedAnnotations' to limit scanning", element);
        } else {
            for (String aPackage : packages) {
                ClassElement[] elements = context.getClassElements(aPackage, includedAnnotations.toArray(new String[0]));
                int j = 0;
                for (ClassElement classElement : elements) {
                    if (classElement.isAbstract() || !classElement.isPublic() || isIntrospected(context, classElement)) {
                        continue;
                    }
                    final BeanIntrospectionWriter writer = new BeanIntrospectionWriter(element.getName(), j++, element, classElement, metadata ? element.getAnnotationMetadata() : null);
                    processElement(metadata, includes, excludes, excludedAnnotations, indexedAnnotations, classElement, writer, finalVisibilities, finalAccessKinds);
                }
            }
        }
    } else {
        final BeanIntrospectionWriter writer = new BeanIntrospectionWriter(element, metadata ? element.getAnnotationMetadata() : null);
        processElement(metadata, includes, excludes, excludedAnnotations, indexedAnnotations, element, writer, finalVisibilities, finalAccessKinds);
    }
}
Also used : AnnotationMetadataHierarchy(io.micronaut.inject.annotation.AnnotationMetadataHierarchy) AnnotationClassValue(io.micronaut.core.annotation.AnnotationClassValue) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata) Introspected(io.micronaut.core.annotation.Introspected) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AnnotationValue(io.micronaut.core.annotation.AnnotationValue)

Example 3 with AnnotationMetadataHierarchy

use of io.micronaut.inject.annotation.AnnotationMetadataHierarchy in project micronaut-core by micronaut-projects.

the class ExecutableMethodsDefinitionWriter method pushNewMethodReference.

private void pushNewMethodReference(ClassWriter classWriter, GeneratorAdapter staticInit, TypedElement declaringType, MethodElement methodElement) {
    staticInit.newInstance(Type.getType(AbstractExecutableMethodsDefinition.MethodReference.class));
    staticInit.dup();
    // 1: declaringType
    Type typeReference = JavaModelUtils.getTypeReference(declaringType.getType());
    staticInit.push(typeReference);
    // 2: annotationMetadata
    AnnotationMetadata annotationMetadata = methodElement.getAnnotationMetadata();
    if (annotationMetadata instanceof AnnotationMetadataHierarchy) {
        annotationMetadata = new AnnotationMetadataHierarchy(new AnnotationMetadataReference(beanDefinitionReferenceClassName, annotationMetadata), annotationMetadata.getDeclaredMetadata());
    }
    pushAnnotationMetadata(classWriter, staticInit, annotationMetadata);
    // 3: methodName
    staticInit.push(methodElement.getName());
    // 4: return argument
    ClassElement genericReturnType = methodElement.getGenericReturnType();
    pushArgument(thisType, classWriter, staticInit, declaringType.getName(), genericReturnType, defaultsStorage, loadTypeMethods);
    // 5: arguments
    ParameterElement[] parameters = methodElement.getSuspendParameters();
    if (parameters.length == 0) {
        staticInit.visitInsn(ACONST_NULL);
    } else {
        pushBuildArgumentsForMethod(typeReference.getClassName(), thisType, classWriter, staticInit, Arrays.asList(parameters), defaultsStorage, loadTypeMethods);
    }
    // 6: isAbstract
    staticInit.push(methodElement.isAbstract());
    // 7: isSuspend
    staticInit.push(methodElement.isSuspend());
    invokeConstructor(staticInit, AbstractExecutableMethodsDefinition.MethodReference.class, Class.class, AnnotationMetadata.class, String.class, Argument.class, Argument[].class, boolean.class, boolean.class);
}
Also used : Type(org.objectweb.asm.Type) Argument(io.micronaut.core.type.Argument) AbstractExecutableMethodsDefinition(io.micronaut.context.AbstractExecutableMethodsDefinition) AnnotationMetadataReference(io.micronaut.inject.annotation.AnnotationMetadataReference) ClassElement(io.micronaut.inject.ast.ClassElement) ParameterElement(io.micronaut.inject.ast.ParameterElement) AnnotationMetadataHierarchy(io.micronaut.inject.annotation.AnnotationMetadataHierarchy) DefaultAnnotationMetadata(io.micronaut.inject.annotation.DefaultAnnotationMetadata) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata)

Example 4 with AnnotationMetadataHierarchy

use of io.micronaut.inject.annotation.AnnotationMetadataHierarchy in project micronaut-core by micronaut-projects.

the class AbstractInterceptorChain method resolveInterceptorValues.

/**
 * Resolve interceptor binding for the given annotation metadata and kind.
 * @param annotationMetadata The annotation metadata
 * @param kind The kind
 * @return The binding
 * @since 3.3.0
 */
@NonNull
protected static Collection<AnnotationValue<?>> resolveInterceptorValues(@NonNull AnnotationMetadata annotationMetadata, @NonNull InterceptorKind kind) {
    if (annotationMetadata instanceof AnnotationMetadataHierarchy) {
        final List<AnnotationValue<InterceptorBinding>> declaredValues = annotationMetadata.getDeclaredMetadata().getAnnotationValuesByType(InterceptorBinding.class);
        final List<AnnotationValue<InterceptorBinding>> parentValues = ((AnnotationMetadataHierarchy) annotationMetadata).getRootMetadata().getAnnotationValuesByType(InterceptorBinding.class);
        if (CollectionUtils.isNotEmpty(declaredValues) || CollectionUtils.isNotEmpty(parentValues)) {
            Set<AnnotationValue<?>> resolved = new HashSet<>(declaredValues.size() + parentValues.size());
            Set<String> declared = new HashSet<>(declaredValues.size());
            for (AnnotationValue<InterceptorBinding> declaredValue : declaredValues) {
                final String annotationName = declaredValue.stringValue().orElse(null);
                if (annotationName != null) {
                    final InterceptorKind specifiedkind = declaredValue.enumValue("kind", InterceptorKind.class).orElse(null);
                    if (specifiedkind == null || specifiedkind.equals(kind)) {
                        if (!annotationMetadata.isRepeatableAnnotation(annotationName)) {
                            declared.add(annotationName);
                        }
                        resolved.add(declaredValue);
                    }
                }
            }
            for (AnnotationValue<InterceptorBinding> parentValue : parentValues) {
                final String annotationName = parentValue.stringValue().orElse(null);
                if (annotationName != null && !declared.contains(annotationName)) {
                    final InterceptorKind specifiedkind = parentValue.enumValue("kind", InterceptorKind.class).orElse(null);
                    if (specifiedkind == null || specifiedkind.equals(kind)) {
                        resolved.add(parentValue);
                    }
                }
            }
            return resolved;
        } else {
            return Collections.emptyList();
        }
    } else {
        List<AnnotationValue<InterceptorBinding>> bindings = annotationMetadata.getAnnotationValuesByType(InterceptorBinding.class);
        if (CollectionUtils.isNotEmpty(bindings)) {
            return bindings.stream().filter(av -> {
                if (!av.stringValue().isPresent()) {
                    return false;
                }
                final InterceptorKind specifiedkind = av.enumValue("kind", InterceptorKind.class).orElse(null);
                return specifiedkind == null || specifiedkind.equals(kind);
            }).collect(Collectors.toSet());
        } else {
            return Collections.emptyList();
        }
    }
}
Also used : InterceptorBinding(io.micronaut.aop.InterceptorBinding) LoggerFactory(org.slf4j.LoggerFactory) InvocationContext(io.micronaut.aop.InvocationContext) Internal(io.micronaut.core.annotation.Internal) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) Nullable(io.micronaut.core.annotation.Nullable) Map(java.util.Map) Argument(io.micronaut.core.type.Argument) MutableConvertibleValues(io.micronaut.core.convert.value.MutableConvertibleValues) MutableArgumentValue(io.micronaut.core.type.MutableArgumentValue) Logger(org.slf4j.Logger) AnnotationMetadataHierarchy(io.micronaut.inject.annotation.AnnotationMetadataHierarchy) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) Collectors(java.util.stream.Collectors) InterceptorKind(io.micronaut.aop.InterceptorKind) NonNull(io.micronaut.core.annotation.NonNull) List(java.util.List) Interceptor(io.micronaut.aop.Interceptor) AnnotationValue(io.micronaut.core.annotation.AnnotationValue) CollectionUtils(io.micronaut.core.util.CollectionUtils) Optional(java.util.Optional) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata) Collections(java.util.Collections) InterceptorBinding(io.micronaut.aop.InterceptorBinding) InterceptorKind(io.micronaut.aop.InterceptorKind) AnnotationValue(io.micronaut.core.annotation.AnnotationValue) AnnotationMetadataHierarchy(io.micronaut.inject.annotation.AnnotationMetadataHierarchy) HashSet(java.util.HashSet) NonNull(io.micronaut.core.annotation.NonNull)

Example 5 with AnnotationMetadataHierarchy

use of io.micronaut.inject.annotation.AnnotationMetadataHierarchy in project micronaut-core by micronaut-projects.

the class ConstructorInterceptorChain method instantiate.

/**
 * Internal methods that handles the logic of instantiating a bean that has constructor interception applied.
 *
 * @param resolutionContext                         The resolution context
 * @param beanContext                               The bean context
 * @param interceptors                              The interceptors. Can be null and if so should be resolved from the context.
 * @param definition                                The definition
 * @param constructor                               The bean constructor
 * @param additionalProxyConstructorParametersCount The additional proxy constructor parameters count
 * @param parameters                                The resolved parameters
 * @param <T1>                                      The bean type
 * @return The instantiated bean
 * @since 3.0.0
 */
@Internal
@UsedByGeneratedCode
@NonNull
public static <T1> T1 instantiate(@NonNull BeanResolutionContext resolutionContext, @NonNull BeanContext beanContext, @Nullable List<BeanRegistration<Interceptor<T1, T1>>> interceptors, @NonNull BeanDefinition<T1> definition, @NonNull BeanConstructor<T1> constructor, int additionalProxyConstructorParametersCount, @NonNull Object... parameters) {
    if (interceptors == null) {
        final AnnotationMetadataHierarchy hierarchy = new AnnotationMetadataHierarchy(definition.getAnnotationMetadata(), constructor.getAnnotationMetadata());
        final Collection<AnnotationValue<?>> annotationValues = resolveInterceptorValues(hierarchy, InterceptorKind.AROUND_CONSTRUCT);
        final Collection<BeanRegistration<Interceptor<?, ?>>> resolved = ((DefaultBeanContext) beanContext).getBeanRegistrations(resolutionContext, Interceptor.ARGUMENT, Qualifiers.byInterceptorBindingValues(annotationValues));
        interceptors = new ArrayList(resolved);
    }
    final InterceptorRegistry interceptorRegistry = beanContext.getBean(InterceptorRegistry.ARGUMENT);
    final Interceptor<T1, T1>[] resolvedInterceptors = interceptorRegistry.resolveConstructorInterceptors(constructor, interceptors);
    return Objects.requireNonNull(new ConstructorInterceptorChain<T1>(definition, constructor, resolvedInterceptors, additionalProxyConstructorParametersCount, parameters).proceed(), "Constructor interceptor chain illegally returned null for constructor: " + constructor.getDescription());
}
Also used : BeanRegistration(io.micronaut.context.BeanRegistration) AnnotationValue(io.micronaut.core.annotation.AnnotationValue) DefaultBeanContext(io.micronaut.context.DefaultBeanContext) AnnotationMetadataHierarchy(io.micronaut.inject.annotation.AnnotationMetadataHierarchy) Internal(io.micronaut.core.annotation.Internal) NonNull(io.micronaut.core.annotation.NonNull) UsedByGeneratedCode(io.micronaut.core.annotation.UsedByGeneratedCode)

Aggregations

AnnotationMetadataHierarchy (io.micronaut.inject.annotation.AnnotationMetadataHierarchy)12 ClassElement (io.micronaut.inject.ast.ClassElement)7 AnnotationMetadata (io.micronaut.core.annotation.AnnotationMetadata)5 AnnotationValue (io.micronaut.core.annotation.AnnotationValue)4 DefaultAnnotationMetadata (io.micronaut.inject.annotation.DefaultAnnotationMetadata)4 BeanDefinitionWriter (io.micronaut.inject.writer.BeanDefinitionWriter)4 Type (org.objectweb.asm.Type)4 Internal (io.micronaut.core.annotation.Internal)3 NonNull (io.micronaut.core.annotation.NonNull)3 Argument (io.micronaut.core.type.Argument)3 ParameterElement (io.micronaut.inject.ast.ParameterElement)3 BeanRegistration (io.micronaut.context.BeanRegistration)2 DefaultBeanContext (io.micronaut.context.DefaultBeanContext)2 Nullable (io.micronaut.core.annotation.Nullable)2 CollectionUtils (io.micronaut.core.util.CollectionUtils)2 AdvisedBeanType (io.micronaut.inject.AdvisedBeanType)2 MutableAnnotationMetadata (io.micronaut.inject.annotation.MutableAnnotationMetadata)2 Collection (java.util.Collection)2 Collections (java.util.Collections)2 HashSet (java.util.HashSet)2