Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.micronaut.inject.annotation.DefaultAnnotationMetadata Maven / Gradle / Ivy
/*
* Copyright 2017-2020 original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.micronaut.inject.annotation;
import io.micronaut.context.exceptions.ConfigurationException;
import io.micronaut.core.annotation.AnnotationClassValue;
import io.micronaut.core.annotation.AnnotationMetadata;
import io.micronaut.core.annotation.AnnotationUtil;
import io.micronaut.core.annotation.AnnotationValue;
import io.micronaut.core.annotation.Internal;
import io.micronaut.core.annotation.NonNull;
import io.micronaut.core.annotation.Nullable;
import io.micronaut.core.annotation.UsedByGeneratedCode;
import io.micronaut.core.convert.ConversionService;
import io.micronaut.core.reflect.ReflectionUtils;
import io.micronaut.core.type.Argument;
import io.micronaut.core.util.ArgumentUtils;
import io.micronaut.core.util.CollectionUtils;
import io.micronaut.core.util.StringUtils;
import io.micronaut.core.value.OptionalValues;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalDouble;
import java.util.OptionalInt;
import java.util.OptionalLong;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* Default implementation of {@link AnnotationMetadata}.
*
*
* NOTE: Although required to be public This is an internal class and should not be referenced directly in user code
*
*
* @author Graeme Rocher
* @since 1.0
*/
@Internal
public class DefaultAnnotationMetadata extends AbstractAnnotationMetadata implements AnnotationMetadata, Cloneable, EnvironmentAnnotationMetadata {
@Nullable
Map> declaredAnnotations;
@Nullable
Map> allAnnotations;
@Nullable
Map> declaredStereotypes;
@Nullable
Map> allStereotypes;
@Nullable
Map> annotationsByStereotype;
private final Map annotationValuesByType = new ConcurrentHashMap<>(2);
private final boolean hasPropertyExpressions;
private final boolean hasEvaluatedExpressions;
/**
* Constructs empty annotation metadata.
*/
@Internal
protected DefaultAnnotationMetadata() {
hasPropertyExpressions = false;
hasEvaluatedExpressions = false;
}
/**
* This constructor is designed to be used by compile time produced subclasses.
*
* @param declaredAnnotations The directly declared annotations
* @param declaredStereotypes The directly declared stereotypes
* @param allStereotypes All stereotypes
* @param allAnnotations All annotations
* @param annotationsByStereotype The annotations by stereotype
*/
@Internal
@UsedByGeneratedCode
public DefaultAnnotationMetadata(
@Nullable Map> declaredAnnotations,
@Nullable Map> declaredStereotypes,
@Nullable Map> allStereotypes,
@Nullable Map> allAnnotations,
@Nullable Map> annotationsByStereotype) {
this(declaredAnnotations, declaredStereotypes, allStereotypes, allAnnotations, annotationsByStereotype, true);
}
/**
* This constructor is designed to be used by compile time produced subclasses.
*
* @param declaredAnnotations The directly declared annotations
* @param declaredStereotypes The directly declared stereotypes
* @param allStereotypes All stereotypes
* @param allAnnotations All annotations
* @param annotationsByStereotype The annotations by stereotype
* @param hasPropertyExpressions Whether property expressions exist in the metadata
*/
@Internal
@UsedByGeneratedCode
public DefaultAnnotationMetadata(
@Nullable Map> declaredAnnotations,
@Nullable Map> declaredStereotypes,
@Nullable Map> allStereotypes,
@Nullable Map> allAnnotations,
@Nullable Map> annotationsByStereotype,
boolean hasPropertyExpressions) {
this(declaredAnnotations, declaredStereotypes, allStereotypes, allAnnotations, annotationsByStereotype, hasPropertyExpressions, false);
}
/**
* This constructor is designed to be used by compile time produced subclasses.
*
* @param declaredAnnotations The directly declared annotations
* @param declaredStereotypes The directly declared stereotypes
* @param allStereotypes All stereotypes
* @param allAnnotations All annotations
* @param annotationsByStereotype The annotations by stereotype
* @param hasPropertyExpressions Whether property expressions exist in the metadata
* @param hasEvaluatedExpressions Whether evaluated expressions exist in the metadata
*/
@Internal
@UsedByGeneratedCode
public DefaultAnnotationMetadata(
@Nullable Map> declaredAnnotations,
@Nullable Map> declaredStereotypes,
@Nullable Map> allStereotypes,
@Nullable Map> allAnnotations,
@Nullable Map> annotationsByStereotype,
boolean hasPropertyExpressions,
boolean hasEvaluatedExpressions) {
this.declaredAnnotations = declaredAnnotations;
this.declaredStereotypes = declaredStereotypes;
this.allStereotypes = allStereotypes;
this.allAnnotations = allAnnotations;
this.annotationsByStereotype = annotationsByStereotype;
this.hasPropertyExpressions = hasPropertyExpressions;
this.hasEvaluatedExpressions = hasEvaluatedExpressions;
}
@NonNull
@Override
public AnnotationMetadata getDeclaredMetadata() {
return new DefaultAnnotationMetadata(
this.declaredAnnotations,
this.declaredStereotypes,
null,
null,
annotationsByStereotype,
hasPropertyExpressions
);
}
@Override
public boolean hasPropertyExpressions() {
return hasPropertyExpressions;
}
@Override
public boolean hasEvaluatedExpressions() {
return hasEvaluatedExpressions;
}
@NonNull
@Override
public Map getDefaultValues(@NonNull String annotation) {
ArgumentUtils.requireNonNull("annotation", annotation);
return AnnotationMetadataSupport.getDefaultValues(annotation);
}
@Override
public boolean isPresent(@NonNull String annotation, @NonNull String member) {
if (allAnnotations == null || StringUtils.isEmpty(annotation)) {
return false;
}
Map values = allAnnotations.get(annotation);
if (values != null) {
return values.containsKey(member);
}
if (allStereotypes != null) {
values = allStereotypes.get(annotation);
if (values != null) {
return values.containsKey(member);
}
}
return false;
}
@Override
public > Optional enumValue(@NonNull String annotation, Class enumType) {
return enumValue(annotation, VALUE_MEMBER, enumType, null);
}
@Override
public > Optional enumValue(@NonNull String annotation, @NonNull String member, Class enumType) {
return enumValue(annotation, member, enumType, null);
}
@Override
public > Optional enumValue(@NonNull Class extends Annotation> annotation, Class enumType) {
return enumValue(annotation, VALUE_MEMBER, enumType);
}
@Override
public > Optional enumValue(@NonNull Class extends Annotation> annotation, @NonNull String member, Class enumType) {
return enumValue(annotation, member, enumType, null);
}
/**
* Retrieve the class value and optionally map its value.
*
* @param annotation The annotation
* @param member The member
* @param enumType The enum type
* @param valueMapper The value mapper
* @param The enum type
* @return The class value
*/
@Override
@Internal
public > Optional enumValue(@NonNull Class extends Annotation> annotation, @NonNull String member, Class enumType, @Nullable Function valueMapper) {
ArgumentUtils.requireNonNull("annotation", annotation);
ArgumentUtils.requireNonNull("member", member);
String repeatableTypeName = findRepeatableAnnotationContainerInternal(annotation.getName());
if (repeatableTypeName != null) {
Object v = getRawSingleValue(repeatableTypeName, VALUE_MEMBER, valueMapper);
if (v instanceof AnnotationValue> annotationValue) {
return annotationValue.enumValue(member, enumType, valueMapper);
}
return Optional.empty();
} else {
return enumValue(annotation.getName(), member, enumType, valueMapper);
}
}
@Override
public > E[] enumValues(@NonNull String annotation, Class enumType) {
return enumValues(annotation, VALUE_MEMBER, enumType, null);
}
@Override
public > E[] enumValues(@NonNull String annotation, @NonNull String member, Class enumType) {
return enumValues(annotation, member, enumType, null);
}
@Override
public > E[] enumValues(@NonNull Class extends Annotation> annotation, Class enumType) {
return enumValues(annotation, VALUE_MEMBER, enumType, null);
}
@Override
public > E[] enumValues(@NonNull Class extends Annotation> annotation, @NonNull String member, Class enumType) {
return enumValues(annotation, member, enumType, null);
}
@Override
public > E[] enumValues(@NonNull Class extends Annotation> annotation, @NonNull String member, Class enumType, @Nullable Function valueMapper) {
ArgumentUtils.requireNonNull("annotation", annotation);
ArgumentUtils.requireNonNull("enumType", enumType);
String repeatableTypeName = findRepeatableAnnotationContainerInternal(annotation.getName());
if (repeatableTypeName != null) {
Object v = getRawValue(repeatableTypeName, member);
if (v instanceof AnnotationValue> annotationValue) {
return annotationValue.enumValues(member, enumType);
}
return (E[]) Array.newInstance(enumType, 0);
} else {
Object v = getRawValue(annotation.getName(), member);
return AnnotationValue.resolveEnumValues(enumType, v);
}
}
@Override
public > E[] enumValues(@NonNull String annotation, @NonNull String member, Class enumType, @Nullable Function valueMapper) {
ArgumentUtils.requireNonNull("annotation", annotation);
ArgumentUtils.requireNonNull("enumType", enumType);
Object v = getRawValue(annotation, member);
return AnnotationValue.resolveEnumValues(enumType, v);
}
/**
* Retrieve the class value and optionally map its value.
*
* @param annotation The annotation
* @param member The member
* @param enumType The enum type
* @param valueMapper The value mapper
* @param The enum type
* @return The class value
*/
@Override
@Internal
public > Optional enumValue(@NonNull String annotation, @NonNull String member, Class enumType, @Nullable Function valueMapper) {
Object rawValue = getRawSingleValue(annotation, member, valueMapper);
return enumValueOf(enumType, rawValue);
}
private > Optional enumValueOf(Class enumType, Object rawValue) {
if (rawValue != null) {
if (enumType.isInstance(rawValue)) {
return Optional.of((E) rawValue);
} else {
try {
return Optional.of(Enum.valueOf(enumType, rawValue.toString()));
} catch (Exception e) {
return Optional.empty();
}
}
}
return Optional.empty();
}
@Override
public Class[] classValues(@NonNull String annotation, @NonNull String member) {
ArgumentUtils.requireNonNull("annotation", annotation);
ArgumentUtils.requireNonNull("member", member);
Object rawSingleValue = getRawValue(annotation, member);
//noinspection unchecked
Class[] classes = (Class[]) AnnotationValue.resolveClassValues(rawSingleValue);
if (classes != null) {
return classes;
}
//noinspection unchecked
return (Class[]) ReflectionUtils.EMPTY_CLASS_ARRAY;
}
@Override
public Class[] classValues(@NonNull Class extends Annotation> annotation, @NonNull String member) {
ArgumentUtils.requireNonNull("annotation", annotation);
ArgumentUtils.requireNonNull("member", member);
String repeatableTypeName = findRepeatableAnnotationContainerInternal(annotation.getName());
if (repeatableTypeName != null) {
Object v = getRawSingleValue(repeatableTypeName, member, null);
if (v instanceof AnnotationValue> annotationValue) {
Class>[] classes = annotationValue.classValues(member);
return (Class[]) classes;
}
//noinspection unchecked
return (Class[]) ReflectionUtils.EMPTY_CLASS_ARRAY;
} else {
return classValues(annotation.getName(), member);
}
}
@NonNull
@Override
public Optional classValue(@NonNull Class extends Annotation> annotation, @NonNull String member) {
return classValue(annotation, member, null);
}
/**
* Retrieve the class value and optionally map its value.
*
* @param annotation The annotation
* @param member The member
* @param valueMapper The value mapper
* @return The class value
*/
@Override
public Optional classValue(@NonNull Class extends Annotation> annotation, @NonNull String member, Function valueMapper) {
ArgumentUtils.requireNonNull("annotation", annotation);
ArgumentUtils.requireNonNull("member", member);
String repeatableTypeName = findRepeatableAnnotationContainerInternal(annotation.getName());
if (repeatableTypeName != null) {
Object v = getRawSingleValue(repeatableTypeName, member, valueMapper);
if (v instanceof AnnotationValue> annotationValue) {
return (Optional) (annotationValue.classValue(member, valueMapper));
}
return Optional.empty();
} else {
return classValue(annotation.getName(), member, valueMapper);
}
}
@NonNull
@Override
public Optional classValue(@NonNull String annotation, @NonNull String member) {
ArgumentUtils.requireNonNull("annotation", annotation);
ArgumentUtils.requireNonNull("member", member);
return classValue(annotation, member, null);
}
/**
* Retrieve the class value and optionally map its value.
*
* @param annotation The annotation
* @param member The member
* @param valueMapper The value mapper
* @return The class value
*/
@Override
@Internal
public Optional classValue(@NonNull String annotation, @NonNull String member, @Nullable Function valueMapper) {
Object rawValue = getRawSingleValue(annotation, member, valueMapper);
if (rawValue instanceof AnnotationClassValue annotationClassValue) {
return annotationClassValue.getType();
} else if (rawValue instanceof Class class1) {
return Optional.of(class1);
} else if (rawValue != null) {
return ConversionService.SHARED.convert(rawValue, Class.class);
}
return Optional.empty();
}
@NonNull
@Override
public OptionalInt intValue(@NonNull String annotation, @NonNull String member) {
ArgumentUtils.requireNonNull("annotation", annotation);
ArgumentUtils.requireNonNull("member", member);
return intValue(annotation, member, null);
}
@NonNull
@Override
public OptionalInt intValue(@NonNull Class extends Annotation> annotation, @NonNull String member) {
return intValue(annotation, member, null);
}
/**
* Retrieve the int value and optionally map its value.
*
* @param annotation The annotation
* @param member The member
* @param valueMapper The value mapper
* @return The int value
*/
@Override
@Internal
public OptionalInt intValue(@NonNull Class extends Annotation> annotation, @NonNull String member, @Nullable Function valueMapper) {
ArgumentUtils.requireNonNull("annotation", annotation);
ArgumentUtils.requireNonNull("member", member);
String repeatableTypeName = findRepeatableAnnotationContainerInternal(annotation.getName());
if (repeatableTypeName != null) {
Object v = getRawSingleValue(repeatableTypeName, VALUE_MEMBER, valueMapper);
if (v instanceof AnnotationValue> annotationValue) {
return annotationValue.intValue(member, valueMapper);
}
return OptionalInt.empty();
} else {
return intValue(annotation.getName(), member, valueMapper);
}
}
@Override
public Optional booleanValue(@NonNull String annotation, @NonNull String member) {
ArgumentUtils.requireNonNull("annotation", annotation);
ArgumentUtils.requireNonNull("member", member);
return booleanValue(annotation, member, null);
}
@Override
public Optional booleanValue(@NonNull Class extends Annotation> annotation, @NonNull String member) {
return booleanValue(annotation, member, null);
}
/**
* Retrieve the boolean value and optionally map its value.
*
* @param annotation The annotation
* @param member The member
* @param valueMapper The value mapper
* @return The boolean value
*/
@Override
public Optional booleanValue(@NonNull Class extends Annotation> annotation, @NonNull String member, Function valueMapper) {
ArgumentUtils.requireNonNull("annotation", annotation);
ArgumentUtils.requireNonNull("member", member);
String repeatableTypeName = findRepeatableAnnotationContainerInternal(annotation.getName());
if (repeatableTypeName != null) {
Object v = getRawSingleValue(repeatableTypeName, VALUE_MEMBER, null);
if (v instanceof AnnotationValue> annotationValue) {
return annotationValue.booleanValue(member, valueMapper);
}
return Optional.empty();
} else {
return booleanValue(annotation.getName(), member, valueMapper);
}
}
/**
* Retrieve the boolean value and optionally map its value.
*
* @param annotation The annotation
* @param member The member
* @param valueMapper The value mapper
* @return The boolean value
*/
@Override
@NonNull
public Optional booleanValue(@NonNull String annotation, @NonNull String member, @Nullable Function valueMapper) {
Object rawValue = getRawSingleValue(annotation, member, valueMapper);
if (rawValue instanceof Boolean aBoolean) {
return Optional.of(aBoolean);
} else if (rawValue != null) {
return Optional.of(StringUtils.isTrue(rawValue.toString()));
}
return Optional.empty();
}
@NonNull
@Override
public OptionalLong longValue(@NonNull String annotation, @NonNull String member) {
ArgumentUtils.requireNonNull("annotation", annotation);
ArgumentUtils.requireNonNull("member", member);
return longValue(annotation, member, null);
}
@NonNull
@Override
public OptionalLong longValue(@NonNull Class extends Annotation> annotation, @NonNull String member) {
return longValue(annotation, member, null);
}
/**
* Retrieve the long value and optionally map its value.
*
* @param annotation The annotation
* @param member The member
* @param valueMapper The value mapper
* @return The long value
*/
@Override
@Internal
public OptionalLong longValue(@NonNull Class extends Annotation> annotation, @NonNull String member, @Nullable Function valueMapper) {
ArgumentUtils.requireNonNull("annotation", annotation);
ArgumentUtils.requireNonNull("member", member);
String repeatableTypeName = findRepeatableAnnotationContainerInternal(annotation.getName());
if (repeatableTypeName != null) {
Object v = getRawSingleValue(repeatableTypeName, VALUE_MEMBER, valueMapper);
if (v instanceof AnnotationValue> annotationValue) {
return annotationValue.longValue(member, valueMapper);
}
return OptionalLong.empty();
} else {
return longValue(annotation.getName(), member, valueMapper);
}
}
/**
* Retrieve the long value and optionally map its value.
*
* @param annotation The annotation
* @param member The member
* @param valueMapper The value mapper
* @return The long value
*/
@Override
@NonNull
public OptionalLong longValue(@NonNull String annotation, @NonNull String member, @Nullable Function valueMapper) {
Object rawValue = getRawSingleValue(annotation, member, valueMapper);
if (rawValue instanceof Number number) {
return OptionalLong.of(number.longValue());
} else if (rawValue instanceof CharSequence) {
final String str = rawValue.toString();
if (StringUtils.isNotEmpty(str)) {
try {
final long i = Long.parseLong(str);
return OptionalLong.of(i);
} catch (NumberFormatException e) {
throw new ConfigurationException("Invalid value [" + str + "] of [" + member + "] of annotation [" + annotation + "]: " + e.getMessage(), e);
}
}
}
return OptionalLong.empty();
}
/**
* Retrieve the int value and optionally map its value.
*
* @param annotation The annotation
* @param member The member
* @param valueMapper The value mapper
* @return The int value
*/
@Override
@NonNull
public OptionalInt intValue(@NonNull String annotation, @NonNull String member, @Nullable Function valueMapper) {
Object rawValue = getRawSingleValue(annotation, member, valueMapper);
if (rawValue instanceof Number number) {
return OptionalInt.of(number.intValue());
} else if (rawValue instanceof CharSequence) {
final String str = rawValue.toString();
if (StringUtils.isNotEmpty(str)) {
try {
final int i = Integer.parseInt(str);
return OptionalInt.of(i);
} catch (NumberFormatException e) {
throw new ConfigurationException("Invalid value [" + str + "] of [" + member + "] of annotation [" + annotation + "]: " + e.getMessage(), e);
}
}
}
return OptionalInt.empty();
}
@NonNull
@Override
public Optional stringValue(@NonNull Class extends Annotation> annotation, @NonNull String member) {
return stringValue(annotation, member, null);
}
/**
* Retrieve the string value and optionally map its value.
*
* @param annotation The annotation
* @param member The member
* @param valueMapper The value mapper
* @return The int value
*/
@Override
public Optional stringValue(@NonNull Class extends Annotation> annotation, @NonNull String member, Function valueMapper) {
ArgumentUtils.requireNonNull("annotation", annotation);
String repeatableTypeName = findRepeatableAnnotationContainerInternal(annotation.getName());
if (repeatableTypeName != null) {
Object v = getRawSingleValue(repeatableTypeName, VALUE_MEMBER, valueMapper);
if (v instanceof AnnotationValue> annotationValue) {
return annotationValue.stringValue(member, valueMapper);
}
return Optional.empty();
} else {
return stringValue(annotation.getName(), member, valueMapper);
}
}
@NonNull
@Override
public String[] stringValues(@NonNull Class extends Annotation> annotation, @NonNull String member) {
return stringValues(annotation.getName(), member, null);
}
@NonNull
@Override
public String[] stringValues(@NonNull String annotation, @NonNull String member) {
return stringValues(annotation, member, null);
}
/**
* Retrieve the string value and optionally map its value.
*
* @param annotation The annotation
* @param member The member
* @param valueMapper The value mapper
* @return The int value
*/
@Override
@NonNull
public String[] stringValues(@NonNull Class extends Annotation> annotation, @NonNull String member, Function valueMapper) {
ArgumentUtils.requireNonNull("annotation", annotation);
String repeatableTypeName = findRepeatableAnnotationContainerInternal(annotation.getName());
if (repeatableTypeName != null) {
Object v = getRawValue(repeatableTypeName, member);
if (v instanceof AnnotationValue> annotationValue) {
return annotationValue.stringValues(member, valueMapper);
}
return StringUtils.EMPTY_STRING_ARRAY;
} else {
Object v = getRawValue(annotation.getName(), member);
String[] strings = AnnotationValue.resolveStringValues(v, valueMapper);
return strings != null ? strings : StringUtils.EMPTY_STRING_ARRAY;
}
}
/**
* Retrieve the string value and optionally map its value.
*
* @param annotation The annotation
* @param member The member
* @param valueMapper The value mapper
* @return The int value
*/
@Override
@NonNull
public String[] stringValues(@NonNull String annotation, @NonNull String member, Function valueMapper) {
ArgumentUtils.requireNonNull("annotation", annotation);
Object v = getRawValue(annotation, member);
String[] strings = AnnotationValue.resolveStringValues(v, valueMapper);
return strings != null ? strings : StringUtils.EMPTY_STRING_ARRAY;
}
@NonNull
@Override
public Optional stringValue(@NonNull String annotation, @NonNull String member) {
ArgumentUtils.requireNonNull("annotation", annotation);
ArgumentUtils.requireNonNull("member", member);
return stringValue(annotation, member, null);
}
/**
* Retrieve the string value and optionally map its value.
*
* @param annotation The annotation
* @param member The member
* @param valueMapper The value mapper
* @return The string value
*/
@Override
@NonNull
public Optional stringValue(@NonNull String annotation, @NonNull String member, @Nullable Function valueMapper) {
Object rawValue = getRawSingleValue(annotation, member, valueMapper);
if (rawValue instanceof String s) {
// Performance optimization to check for the actual class first to avoid the type-check polution
return Optional.of(s);
} else if (rawValue instanceof CharSequence) {
return Optional.of(rawValue.toString());
} else if (rawValue instanceof Class> aClass) {
String name = aClass.getName();
return Optional.of(name);
} else if (rawValue != null) {
return Optional.of(rawValue.toString());
}
return Optional.empty();
}
@Override
public boolean isTrue(@NonNull Class extends Annotation> annotation, @NonNull String member) {
return isTrue(annotation, member, null);
}
/**
* Retrieve the boolean value and optionally map its value.
*
* @param annotation The annotation
* @param member The member
* @param valueMapper The value mapper
* @return The boolean value
*/
@Override
public boolean isTrue(@NonNull Class extends Annotation> annotation, @NonNull String member, Function valueMapper) {
ArgumentUtils.requireNonNull("annotation", annotation);
ArgumentUtils.requireNonNull("member", member);
String repeatableTypeName = findRepeatableAnnotationContainerInternal(annotation.getName());
if (repeatableTypeName != null) {
Object v = getRawSingleValue(repeatableTypeName, VALUE_MEMBER, valueMapper);
if (v instanceof AnnotationValue> annotationValue) {
return annotationValue.isTrue(member, valueMapper);
}
return false;
} else {
return isTrue(annotation.getName(), member, valueMapper);
}
}
@Override
public boolean isTrue(@NonNull String annotation, @NonNull String member) {
ArgumentUtils.requireNonNull("annotation", annotation);
ArgumentUtils.requireNonNull("member", member);
return isTrue(annotation, member, null);
}
/**
* Retrieve the boolean value and optionally map its value.
*
* @param annotation The annotation
* @param member The member
* @param valueMapper The value mapper
* @return The boolean value
*/
@Override
public boolean isTrue(@NonNull String annotation, @NonNull String member, @Nullable Function valueMapper) {
Object rawValue = getRawSingleValue(annotation, member, valueMapper);
if (rawValue instanceof Boolean aBoolean) {
return aBoolean;
} else if (rawValue != null) {
String booleanString = rawValue.toString().toLowerCase(Locale.ENGLISH);
return StringUtils.isTrue(booleanString);
}
return false;
}
@Override
public boolean isFalse(@NonNull String annotation, @NonNull String member) {
return !isTrue(annotation, member);
}
@NonNull
@Override
public OptionalDouble doubleValue(@NonNull String annotation, @NonNull String member) {
ArgumentUtils.requireNonNull("annotation", annotation);
ArgumentUtils.requireNonNull("member", member);
return doubleValue(annotation, member, null);
}
@NonNull
@Override
public OptionalDouble doubleValue(@NonNull Class extends Annotation> annotation, @NonNull String member) {
return doubleValue(annotation, member, null);
}
/**
* Retrieve the double value and optionally map its value.
*
* @param annotation The annotation
* @param member The member
* @param valueMapper The value mapper
* @return The double value
*/
@Override
@Internal
public OptionalDouble doubleValue(@NonNull Class extends Annotation> annotation, @NonNull String member, @Nullable Function valueMapper) {
ArgumentUtils.requireNonNull("annotation", annotation);
ArgumentUtils.requireNonNull("member", member);
String repeatableTypeName = findRepeatableAnnotationContainerInternal(annotation.getName());
if (repeatableTypeName != null) {
Object v = getRawSingleValue(repeatableTypeName, VALUE_MEMBER, valueMapper);
if (v instanceof AnnotationValue> annotationValue) {
return annotationValue.doubleValue(member, valueMapper);
}
return OptionalDouble.empty();
} else {
return doubleValue(annotation.getName(), member);
}
}
/**
* Retrieve the double value and optionally map its value.
*
* @param annotation The annotation
* @param member The member
* @param valueMapper The value mapper
* @return The double value
*/
@Override
@NonNull
@Internal
public OptionalDouble doubleValue(@NonNull String annotation, @NonNull String member, Function valueMapper) {
Object rawValue = getRawSingleValue(annotation, member, valueMapper);
if (rawValue instanceof Number number) {
return OptionalDouble.of(number.doubleValue());
} else if (rawValue instanceof CharSequence) {
final String str = rawValue.toString();
if (StringUtils.isNotEmpty(str)) {
try {
final double i = Double.parseDouble(str);
return OptionalDouble.of(i);
} catch (NumberFormatException e) {
throw new ConfigurationException("Invalid value [" + str + "] of member [" + member + "] of annotation [" + annotation + "]: " + e.getMessage(), e);
}
}
}
return OptionalDouble.empty();
}
@Override
public @NonNull Optional getValue(@NonNull Class extends Annotation> annotation, @NonNull String member, @NonNull Class requiredType) {
ArgumentUtils.requireNonNull("annotation", annotation);
ArgumentUtils.requireNonNull("member", member);
ArgumentUtils.requireNonNull("requiredType", requiredType);
String repeatableTypeName = findRepeatableAnnotationContainerInternal(annotation.getName());
if (repeatableTypeName != null) {
List extends AnnotationValue extends Annotation>> values = getAnnotationValuesByType(annotation);
if (!values.isEmpty()) {
return values.iterator().next().get(member, requiredType);
} else {
return Optional.empty();
}
} else {
return getValue(annotation.getName(), member, requiredType);
}
}
@Override
public @NonNull Optional getValue(@NonNull String annotation, @NonNull String member, @NonNull Argument requiredType) {
return getValue(annotation, member, requiredType, null);
}
/**
* Resolves the given value performing type conversion as necessary.
*
* @param annotation The annotation
* @param member The member
* @param requiredType The required type
* @param valueMapper The value mapper
* @param The generic type
* @return The resolved value
*/
@Override
@NonNull
public Optional getValue(@NonNull String annotation, @NonNull String member, @NonNull Argument requiredType, @Nullable Function valueMapper) {
ArgumentUtils.requireNonNull("annotation", annotation);
ArgumentUtils.requireNonNull("member", member);
ArgumentUtils.requireNonNull("requiredType", requiredType);
Optional resolved = Optional.empty();
if (allAnnotations != null && StringUtils.isNotEmpty(annotation)) {
Map values = allAnnotations.get(annotation);
if (values != null) {
Object rawValue = values.get(member);
if (rawValue != null) {
if (valueMapper != null) {
rawValue = valueMapper.apply(rawValue);
}
resolved = ConversionService.SHARED.convert(rawValue, requiredType);
}
} else if (allStereotypes != null) {
values = allStereotypes.get(annotation);
if (values != null) {
Object rawValue = values.get(member);
if (rawValue != null) {
if (valueMapper != null) {
rawValue = valueMapper.apply(rawValue);
}
resolved = ConversionService.SHARED.convert(rawValue, requiredType);
}
}
}
}
if (resolved.isEmpty() && hasStereotype(annotation)) {
return getDefaultValue(annotation, member, requiredType);
}
return resolved;
}
@Override
public @NonNull Optional getDefaultValue(@NonNull String annotation, @NonNull String member, @NonNull Class requiredType) {
ArgumentUtils.requireNonNull("annotation", annotation);
ArgumentUtils.requireNonNull("member", member);
ArgumentUtils.requireNonNull("requiredType", requiredType);
Map defaultValues = getDefaultValues(annotation);
final Object v = defaultValues.get(member);
if (v == null) {
return Optional.empty();
}
if (requiredType.isInstance(v)) {
return (Optional) Optional.of(v);
}
return ConversionService.SHARED.convert(v, requiredType);
}
@SuppressWarnings("unchecked")
@Override
public @NonNull List> getAnnotationValuesByType(@Nullable Class annotationType) {
if (annotationType == null) {
return List.of();
}
final String annotationTypeName = annotationType.getName();
List> results = annotationValuesByType.get(annotationTypeName);
if (results == null) {
results = resolveAnnotationValuesByType(annotationType, allAnnotations, allStereotypes);
if (results != null) {
return results;
} else if (allAnnotations != null) {
final Map values = allAnnotations.get(annotationTypeName);
if (values != null) {
results = List.of(newAnnotationValue(annotationTypeName, values));
}
}
if (results == null) {
results = List.of();
}
annotationValuesByType.put(annotationTypeName, results);
}
return results;
}
@Override
public List> getAnnotationValuesByName(String annotationType) {
if (annotationType == null) {
return List.of();
}
String repeatableTypeName = findRepeatableAnnotationContainerInternal(annotationType);
if (repeatableTypeName == null) {
return List.of();
}
List> results = resolveRepeatableAnnotations(repeatableTypeName, allAnnotations, allStereotypes);
if (results != null) {
return results;
}
if (allAnnotations != null) {
final Map values = allAnnotations.get(annotationType);
if (values != null) {
results = List.of(newAnnotationValue(annotationType, values));
}
}
if (results == null) {
results = List.of();
}
annotationValuesByType.put(annotationType, results);
return List.of();
}
@NonNull
protected AnnotationValue newAnnotationValue(String annotationType, Map values) {
return new AnnotationValue<>(annotationType, values, AnnotationMetadataSupport.getDefaultValuesOrNull(annotationType));
}
@NonNull
@Override
public List> getDeclaredAnnotationValuesByType(@NonNull Class annotationType) {
if (annotationType == null) {
return List.of();
}
List> results = resolveAnnotationValuesByType(annotationType, declaredAnnotations, declaredStereotypes);
if (results != null) {
return results;
}
return List.of();
}
@Override
public List> getDeclaredAnnotationValuesByName(String annotationType) {
if (annotationType == null) {
return List.of();
}
String repeatableTypeName = findRepeatableAnnotationContainerInternal(annotationType);
List> results = resolveRepeatableAnnotations(repeatableTypeName, declaredAnnotations, declaredStereotypes);
if (results != null) {
return results;
}
return List.of();
}
@SuppressWarnings("unchecked")
@Override
public T[] synthesizeAnnotationsByType(@NonNull Class annotationClass) {
if (annotationClass == null) {
return (T[]) AnnotationUtil.ZERO_ANNOTATIONS;
}
return getAnnotationValuesByType(annotationClass).stream()
.map(entries -> AnnotationMetadataSupport.buildAnnotation(annotationClass, entries))
.toArray(value -> (T[]) Array.newInstance(annotationClass, value));
}
@Override
public T[] synthesizeDeclaredAnnotationsByType(@NonNull Class annotationClass) {
if (annotationClass == null) {
return (T[]) AnnotationUtil.ZERO_ANNOTATIONS;
}
return getAnnotationValuesByType(annotationClass).stream()
.map(entries -> AnnotationMetadataSupport.buildAnnotation(annotationClass, entries))
.toArray(value -> (T[]) Array.newInstance(annotationClass, value));
}
@Override
public boolean isEmpty() {
return allAnnotations == null || allAnnotations.isEmpty();
}
@Override
public boolean hasDeclaredAnnotation(String annotation) {
return declaredAnnotations != null && StringUtils.isNotEmpty(annotation) && declaredAnnotations.containsKey(annotation);
}
@Override
public boolean hasAnnotation(String annotation) {
return hasDeclaredAnnotation(annotation) || (allAnnotations != null && StringUtils.isNotEmpty(annotation) && allAnnotations.containsKey(annotation));
}
@Override
public boolean hasStereotype(String annotation) {
return hasAnnotation(annotation) || (allStereotypes != null && StringUtils.isNotEmpty(annotation) && allStereotypes.containsKey(annotation));
}
@Override
public boolean hasDeclaredStereotype(String annotation) {
return hasDeclaredAnnotation(annotation) || (declaredStereotypes != null && StringUtils.isNotEmpty(annotation) && declaredStereotypes.containsKey(annotation));
}
@NonNull
@Override
public Optional> getAnnotationTypeByStereotype(@Nullable String stereotype) {
if (stereotype == null) {
return Optional.empty();
}
if (annotationsByStereotype != null) {
List annotations = annotationsByStereotype.get(stereotype);
if (CollectionUtils.isNotEmpty(annotations)) {
return getAnnotationType(annotations.get(0));
}
}
if (allAnnotations != null && allAnnotations.containsKey(stereotype)) {
return getAnnotationType(stereotype);
}
if (declaredAnnotations != null && declaredAnnotations.containsKey(stereotype)) {
return getAnnotationType(stereotype);
}
return Optional.empty();
}
@NonNull
@Override
public Optional getAnnotationNameByStereotype(@Nullable String stereotype) {
if (stereotype == null) {
return Optional.empty();
}
if (annotationsByStereotype != null) {
List annotations = annotationsByStereotype.get(stereotype);
if (CollectionUtils.isNotEmpty(annotations)) {
return Optional.of(annotations.get(0));
}
}
if (allAnnotations != null && allAnnotations.containsKey(stereotype)) {
return Optional.of(stereotype);
}
if (declaredAnnotations != null && declaredAnnotations.containsKey(stereotype)) {
return Optional.of(stereotype);
}
return Optional.empty();
}
@NonNull
@Override
public List getAnnotationNamesByStereotype(@Nullable String stereotype) {
if (stereotype == null) {
return List.of();
}
if (annotationsByStereotype != null) {
List annotations = annotationsByStereotype.get(stereotype);
if (annotations != null) {
return Collections.unmodifiableList(annotations);
}
}
if (allAnnotations != null && allAnnotations.containsKey(stereotype)) {
return List.of(stereotype);
}
if (declaredAnnotations != null && declaredAnnotations.containsKey(stereotype)) {
return List.of(stereotype);
}
return List.of();
}
@Override
public List> getAnnotationValuesByStereotype(String stereotype) {
if (stereotype == null) {
return List.of();
}
if (annotationsByStereotype != null) {
List annotations = annotationsByStereotype.get(stereotype);
if (annotations != null) {
List> result = new ArrayList<>(annotations.size());
for (String annotation : annotations) {
String repeatableTypeName = findRepeatableAnnotationContainerInternal(annotation);
if (repeatableTypeName != null) {
List> results =
resolveRepeatableAnnotations(repeatableTypeName,
allAnnotations,
allStereotypes
);
if (results != null) {
result.addAll(results);
}
} else {
result.add(getAnnotation(annotation));
}
}
return Collections.unmodifiableList(result);
}
}
if (allAnnotations != null) {
return getAnnotationValuesByName(stereotype);
}
if (declaredAnnotations != null) {
return getDeclaredAnnotationValuesByName(stereotype);
}
return List.of();
}
@NonNull
@Override
public Set getAnnotationNames() {
if (allAnnotations != null) {
return Collections.unmodifiableSet(allAnnotations.keySet());
}
return Set.of();
}
@NonNull
@Override
public Set getStereotypeAnnotationNames() {
if (allStereotypes != null) {
return Collections.unmodifiableSet(allStereotypes.keySet());
}
return Set.of();
}
@NonNull
@Override
public Set getDeclaredStereotypeAnnotationNames() {
if (declaredStereotypes != null) {
return Collections.unmodifiableSet(declaredStereotypes.keySet());
}
return Set.of();
}
@NonNull
@Override
public Set getDeclaredAnnotationNames() {
if (declaredAnnotations != null) {
return Collections.unmodifiableSet(declaredAnnotations.keySet());
}
return Set.of();
}
@NonNull
@Override
public List getDeclaredAnnotationNamesByStereotype(@Nullable String stereotype) {
if (stereotype == null) {
return List.of();
}
if (annotationsByStereotype != null) {
List annotations = annotationsByStereotype.get(stereotype);
if (annotations != null) {
annotations = new ArrayList<>(annotations);
if (declaredAnnotations != null) {
annotations.removeIf(s -> !declaredAnnotations.containsKey(s));
return Collections.unmodifiableList(annotations);
} else {
// no declared
return List.of();
}
}
}
if (declaredAnnotations != null && declaredAnnotations.containsKey(stereotype)) {
return List.of(stereotype);
}
return List.of();
}
@NonNull
@Override
public Optional> getAnnotationType(@NonNull String name) {
return AnnotationMetadataSupport.getAnnotationType(name);
}
@NonNull
@Override
public Optional> getAnnotationType(@NonNull String name, @NonNull ClassLoader classLoader) {
return AnnotationMetadataSupport.getAnnotationType(name, classLoader);
}
@SuppressWarnings("Duplicates")
@NonNull
@Override
public Optional> findAnnotation(@NonNull String annotation) {
ArgumentUtils.requireNonNull("annotation", annotation);
if (allAnnotations == null || StringUtils.isEmpty(annotation)) {
return Optional.empty();
}
Map values = allAnnotations.get(annotation);
if (values != null) {
return Optional.of(newAnnotationValue(annotation, values));
}
if (allStereotypes != null) {
values = allStereotypes.get(annotation);
if (values != null) {
return Optional.of(newAnnotationValue(annotation, values));
}
}
return Optional.empty();
}
@SuppressWarnings("Duplicates")
@NonNull
@Override
public Optional> findDeclaredAnnotation(@NonNull String annotation) {
ArgumentUtils.requireNonNull("annotation", annotation);
if (declaredAnnotations == null || StringUtils.isEmpty(annotation)) {
return Optional.empty();
}
Map values = declaredAnnotations.get(annotation);
if (values != null) {
return Optional.of(newAnnotationValue(annotation, values));
}
if (declaredStereotypes != null) {
values = declaredStereotypes.get(annotation);
if (values != null) {
return Optional.of(newAnnotationValue(annotation, values));
}
}
return Optional.empty();
}
@Override
public @NonNull OptionalValues getValues(@NonNull String annotation, @NonNull Class valueType) {
ArgumentUtils.requireNonNull("annotation", annotation);
ArgumentUtils.requireNonNull("valueType", valueType);
if (allAnnotations == null || StringUtils.isEmpty(annotation)) {
return OptionalValues.empty();
}
Map values = allAnnotations.get(annotation);
if (values != null) {
return OptionalValues.of(valueType, values);
}
if (allStereotypes != null) {
values = allStereotypes.get(annotation);
if (values != null) {
return OptionalValues.of(valueType, values);
}
}
return OptionalValues.empty();
}
@NonNull
@Override
public Map getValues(@NonNull String annotation) {
ArgumentUtils.requireNonNull("annotation", annotation);
if (allAnnotations == null || StringUtils.isEmpty(annotation)) {
return Collections.emptyMap();
}
Map values = allAnnotations.get(annotation);
if (values != null) {
return Collections.unmodifiableMap(values);
}
if (allStereotypes != null) {
values = allStereotypes.get(annotation);
if (values != null) {
return Collections.unmodifiableMap(values);
}
}
return Collections.emptyMap();
}
@NonNull
@Override
public Optional getDefaultValue(@NonNull String annotation, @NonNull String member, @NonNull Argument requiredType) {
ArgumentUtils.requireNonNull("annotation", annotation);
ArgumentUtils.requireNonNull("member", member);
ArgumentUtils.requireNonNull("requiredType", requiredType);
// Note this method should never reference the "annotationDefaultValues" field, which is used only at compile time
Map defaultValues = getDefaultValues(annotation);
Object value = defaultValues.get(member);
if (value != null) {
return ConversionService.SHARED.convert(value, requiredType);
}
return Optional.empty();
}
@Override
public boolean isRepeatableAnnotation(Class extends Annotation> annotation) {
return isRepeatableAnnotation(annotation.getName());
}
@Override
public boolean isRepeatableAnnotation(String annotation) {
return findRepeatableAnnotationContainerInternal(annotation) != null;
}
@Override
public Optional findRepeatableAnnotation(Class extends Annotation> annotation) {
return findRepeatableAnnotation(annotation.getName());
}
@Override
public Optional findRepeatableAnnotation(String annotation) {
return Optional.ofNullable(findRepeatableAnnotationContainerInternal(annotation));
}
@Override
public AnnotationMetadata copyAnnotationMetadata() {
return clone();
}
@Override
public DefaultAnnotationMetadata clone() {
DefaultAnnotationMetadata cloned = new DefaultAnnotationMetadata(
declaredAnnotations != null ? cloneMapOfMapValue(declaredAnnotations) : null,
declaredStereotypes != null ? cloneMapOfMapValue(declaredStereotypes) : null,
allStereotypes != null ? cloneMapOfMapValue(allStereotypes) : null,
allAnnotations != null ? cloneMapOfMapValue(allAnnotations) : null,
annotationsByStereotype != null ? cloneMapOfListValue(annotationsByStereotype) : null,
hasPropertyExpressions
);
return cloned;
}
protected final Map> cloneMapOfMapValue(Map> toClone) {
return toClone.entrySet().stream()
.map(e -> new AbstractMap.SimpleEntry<>(e.getKey(), cloneMap(e.getValue())))
.collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue, (a, b) -> a, LinkedHashMap::new));
}
protected final Map> cloneMapOfListValue(Map> toClone) {
return toClone.entrySet().stream()
.map(e -> new AbstractMap.SimpleEntry<>(e.getKey(), new ArrayList<>(e.getValue())))
.collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue, (a, b) -> a, LinkedHashMap::new));
}
protected final Map cloneMap(Map map) {
Map newMap;
if (map instanceof LinkedHashMap linkedHashMap) {
newMap = (Map) linkedHashMap.clone();
} else {
newMap = new LinkedHashMap<>(map);
}
for (Map.Entry entry : newMap.entrySet()) {
if (entry.getValue() instanceof Set) {
LinkedHashSet newValue = new LinkedHashSet<>((Collection) entry.getValue());
entry.setValue((V) newValue);
}
}
return new HashMap<>(newMap);
}
/**
* Registers annotation default values. Used by generated byte code. DO NOT REMOVE.
*
* @param annotation The annotation name
* @param defaultValues The default values
*/
@SuppressWarnings("unused")
@Internal
@UsedByGeneratedCode
public static void registerAnnotationDefaults(String annotation, Map defaultValues) {
AnnotationMetadataSupport.registerDefaultValues(annotation, defaultValues);
}
/**
* Registers annotation default values. Used by generated byte code. DO NOT REMOVE.
*
* @param annotation The annotation name
* @param defaultValues The default values
*/
@SuppressWarnings("unused")
@Internal
@UsedByGeneratedCode
public static void registerAnnotationDefaults(AnnotationClassValue> annotation, Map defaultValues) {
AnnotationMetadataSupport.registerDefaultValues(annotation, defaultValues);
}
/**
* Registers annotation default values. Used by generated byte code. DO NOT REMOVE.
*
* @param annotation The annotation
*/
@SuppressWarnings("unused")
@Internal
@UsedByGeneratedCode
public static void registerAnnotationType(AnnotationClassValue> annotation) {
AnnotationMetadataSupport.registerAnnotationType(annotation);
}
/**
* Registers repeatable annotations. Annotation container -> annotations item. Used by generated byte code. DO NOT REMOVE.
*
* @param repeatableAnnotations The annotation
*/
@SuppressWarnings("unused")
@Internal
@UsedByGeneratedCode
public static void registerRepeatableAnnotations(Map repeatableAnnotations) {
AnnotationMetadataSupport.registerRepeatableAnnotations(repeatableAnnotations);
}
/**
* Dump the values.
*/
@SuppressWarnings("unused")
@Internal
void dump() {
System.out.println("declaredAnnotations = " + declaredAnnotations);
System.out.println("declaredStereotypes = " + declaredStereotypes);
System.out.println("allAnnotations = " + allAnnotations);
System.out.println("allStereotypes = " + allStereotypes);
System.out.println("annotationsByStereotype = " + annotationsByStereotype);
}
private List> resolveAnnotationValuesByType(Class annotationType, Map> sourceAnnotations, Map> sourceStereotypes) {
String repeatableTypeName = findRepeatableAnnotationContainerInternal(annotationType.getName());
if (repeatableTypeName != null) {
return resolveRepeatableAnnotations(repeatableTypeName,
sourceStereotypes,
sourceAnnotations
);
}
return null;
}
@Nullable
private List> resolveRepeatableAnnotations(String repeatableTypeName,
Map> sourceStereotypes,
Map> sourceAnnotations) {
if (!hasStereotype(repeatableTypeName)) {
return null;
}
List> results = null;
if (sourceAnnotations != null) {
Map values = sourceAnnotations.get(repeatableTypeName);
results = collectResult(results, values);
}
if (sourceStereotypes != null) {
Map values = sourceStereotypes.get(repeatableTypeName);
results = collectResult(results, values);
}
return results == null ? List.of() : results;
}
@Nullable
private Object getRawSingleValue(@NonNull String annotation, @NonNull String member, @Nullable Function valueMapper) {
Object rawValue = getRawValue(annotation, member);
if (rawValue != null) {
if (rawValue.getClass().isArray()) {
int len = Array.getLength(rawValue);
if (len > 0) {
rawValue = Array.get(rawValue, 0);
}
} else if (rawValue instanceof Iterable> iterable) {
Iterator> i = iterable.iterator();
if (i.hasNext()) {
rawValue = i.next();
}
}
}
if (valueMapper != null && rawValue instanceof CharSequence) {
return valueMapper.apply(rawValue);
} else {
return rawValue;
}
}
@Nullable
private Object getRawValue(@NonNull String annotation, @NonNull String member) {
if (allAnnotations == null || StringUtils.isEmpty(annotation)) {
return null;
}
Map values = allAnnotations.get(annotation);
if (values != null) {
return values.get(member);
}
if (allStereotypes != null) {
values = allStereotypes.get(annotation);
if (values != null) {
return values.get(member);
}
}
return null;
}
/**
* Find annotation's repeatable container.
* @param annotation The annotation
* @return the repeatable container or null
*/
@Nullable
protected String findRepeatableAnnotationContainerInternal(@NonNull String annotation) {
return AnnotationMetadataSupport.getRepeatableAnnotation(annotation);
}
private List> collectResult(List> results, Map values) {
if (values != null) {
Object v = values.get(AnnotationMetadata.VALUE_MEMBER);
if (v instanceof AnnotationValue>[] avs) {
List> result = (List) Arrays.asList(avs);
if (results == null) {
return result;
} else {
return CollectionUtils.concat(results, result);
}
} else if (v instanceof Collection> c) {
List> result = new ArrayList<>(c.size());
for (Object o : c) {
if (o instanceof io.micronaut.core.annotation.AnnotationValue> av) {
result.add((AnnotationValue) av);
}
}
if (results == null) {
return result;
} else {
return CollectionUtils.concat(results, result);
}
}
}
return results;
}
}