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;
}
};
}
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);
}
}
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);
}
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();
}
}
}
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());
}
Aggregations