use of io.micronaut.inject.visitor.VisitorContext in project micronaut-core by micronaut-projects.
the class AbstractAnnotationMetadataBuilder method applyTransformationsForAnnotationType.
private void applyTransformationsForAnnotationType(@Nullable ListIterator<? extends A> hierarchyIterator, DefaultAnnotationMetadata annotationMetadata, boolean isDeclared, @NonNull T annotationType, Map<CharSequence, Object> data, List<String> parents, @Nullable LinkedList<AnnotationValueBuilder<?>> interceptorBindings, BiConsumer<String, AnnotationValue> addRepeatableAnnotation, TriConsumer<String, Map<CharSequence, Object>, RetentionPolicy> addAnnotation) {
String annotationName = getElementName(annotationType);
String packageName = NameUtils.getPackageName(annotationName);
String repeatableName = getRepeatableNameForType(annotationType);
RetentionPolicy retentionPolicy = getRetentionPolicy(annotationType);
List<AnnotationRemapper> annotationRemappers = ANNOTATION_REMAPPERS.get(packageName);
List<AnnotationTransformer<Annotation>> annotationTransformers = getAnnotationTransformers(annotationName);
boolean remapped = CollectionUtils.isNotEmpty(annotationRemappers);
boolean transformed = CollectionUtils.isNotEmpty(annotationTransformers);
if (repeatableName != null) {
if (!remapped && !transformed) {
io.micronaut.core.annotation.AnnotationValue av = new io.micronaut.core.annotation.AnnotationValue(annotationName, data);
addRepeatableAnnotation.accept(repeatableName, av);
} else if (remapped) {
VisitorContext visitorContext = createVisitorContext();
io.micronaut.core.annotation.AnnotationValue<?> av = new io.micronaut.core.annotation.AnnotationValue<>(annotationName, data);
AnnotationValue<?> repeatableAnn = AnnotationValue.builder(repeatableName).values(av).build();
boolean wasRemapped = false;
for (AnnotationRemapper annotationRemapper : annotationRemappers) {
List<AnnotationValue<?>> remappedRepeatable = annotationRemapper.remap(repeatableAnn, visitorContext);
List<AnnotationValue<?>> remappedValue = annotationRemapper.remap(av, visitorContext);
if (CollectionUtils.isNotEmpty(remappedRepeatable)) {
for (AnnotationValue<?> repeatable : remappedRepeatable) {
for (AnnotationValue<?> rmv : remappedValue) {
if (rmv == av && remappedValue.size() == 1) {
// bail, the re-mapper just returned the same annotation
addRepeatableAnnotation.accept(repeatableName, av);
break;
} else {
wasRemapped = true;
addRepeatableAnnotation.accept(repeatable.getAnnotationName(), rmv);
}
}
}
}
}
if (wasRemapped && hierarchyIterator != null) {
hierarchyIterator.remove();
}
} else {
VisitorContext visitorContext = createVisitorContext();
io.micronaut.core.annotation.AnnotationValue<Annotation> av = new io.micronaut.core.annotation.AnnotationValue<>(annotationName, data);
AnnotationValue<Annotation> repeatableAnn = AnnotationValue.builder(repeatableName).values(av).build();
final List<AnnotationTransformer<Annotation>> repeatableTransformers = getAnnotationTransformers(repeatableName);
if (hierarchyIterator != null) {
hierarchyIterator.remove();
}
if (CollectionUtils.isNotEmpty(repeatableTransformers)) {
for (AnnotationTransformer<Annotation> repeatableTransformer : repeatableTransformers) {
final List<AnnotationValue<?>> transformedRepeatable = repeatableTransformer.transform(repeatableAnn, visitorContext);
for (AnnotationValue<?> annotationValue : transformedRepeatable) {
for (AnnotationTransformer<Annotation> transformer : annotationTransformers) {
final List<AnnotationValue<?>> tav = transformer.transform(av, visitorContext);
for (AnnotationValue<?> value : tav) {
addRepeatableAnnotation.accept(annotationValue.getAnnotationName(), value);
if (CollectionUtils.isNotEmpty(value.getStereotypes())) {
addTransformedStereotypes(annotationMetadata, isDeclared, value, parents);
} else {
addTransformedStereotypes(annotationMetadata, isDeclared, value.getAnnotationName(), parents);
}
}
}
}
}
} else {
for (AnnotationTransformer<Annotation> transformer : annotationTransformers) {
final List<AnnotationValue<?>> tav = transformer.transform(av, visitorContext);
for (AnnotationValue<?> value : tav) {
addRepeatableAnnotation.accept(repeatableName, value);
if (CollectionUtils.isNotEmpty(value.getStereotypes())) {
addTransformedStereotypes(annotationMetadata, isDeclared, value, parents);
} else {
addTransformedStereotypes(annotationMetadata, isDeclared, value.getAnnotationName(), parents);
}
}
}
}
}
} else {
if (!remapped && !transformed) {
addAnnotation.accept(annotationName, data, retentionPolicy);
} else if (remapped) {
io.micronaut.core.annotation.AnnotationValue<?> av = new io.micronaut.core.annotation.AnnotationValue(annotationName, data);
VisitorContext visitorContext = createVisitorContext();
boolean wasRemapped = false;
for (AnnotationRemapper annotationRemapper : annotationRemappers) {
List<AnnotationValue<?>> remappedValues = annotationRemapper.remap(av, visitorContext);
if (CollectionUtils.isNotEmpty(remappedValues)) {
for (AnnotationValue<?> annotationValue : remappedValues) {
if (annotationValue == av && remappedValues.size() == 1) {
// bail, the re-mapper just returned the same annotation
addAnnotation.accept(annotationName, data, retentionPolicy);
break;
} else {
wasRemapped = true;
final String transformedAnnotationName = handleTransformedAnnotationValue(parents, interceptorBindings, addRepeatableAnnotation, addAnnotation, annotationValue, annotationMetadata);
if (CollectionUtils.isNotEmpty(annotationValue.getStereotypes())) {
addTransformedStereotypes(annotationMetadata, isDeclared, annotationValue, parents);
} else {
addTransformedStereotypes(annotationMetadata, isDeclared, transformedAnnotationName, parents);
}
}
}
}
}
if (wasRemapped && hierarchyIterator != null) {
hierarchyIterator.remove();
}
} else {
io.micronaut.core.annotation.AnnotationValue<Annotation> av = new io.micronaut.core.annotation.AnnotationValue<>(annotationName, data);
VisitorContext visitorContext = createVisitorContext();
if (hierarchyIterator != null) {
hierarchyIterator.remove();
}
for (AnnotationTransformer<Annotation> annotationTransformer : annotationTransformers) {
final List<AnnotationValue<?>> transformedValues = annotationTransformer.transform(av, visitorContext);
for (AnnotationValue<?> transformedValue : transformedValues) {
final String transformedAnnotationName = handleTransformedAnnotationValue(parents, interceptorBindings, addRepeatableAnnotation, addAnnotation, transformedValue, annotationMetadata);
if (CollectionUtils.isNotEmpty(transformedValue.getStereotypes())) {
addTransformedStereotypes(annotationMetadata, isDeclared, transformedValue, parents);
} else {
addTransformedStereotypes(annotationMetadata, isDeclared, transformedAnnotationName, parents);
}
}
}
}
}
}
use of io.micronaut.inject.visitor.VisitorContext in project micronaut-core by micronaut-projects.
the class AbstractAnnotationMetadataBuilder method populateAnnotationData.
/**
* Populate the annotation data for the given annotation.
*
* @param originatingElement The element the annotation data originates from
* @param originatingElementIsSameParent Whether the originating element is considered a parent element
* @param annotationMirror The annotation
* @param metadata the metadata
* @param isDeclared Is the annotation a declared annotation
* @param retentionPolicy The retention policy
* @param allowAliases Whether aliases are allowed
* @return The annotation values
*/
protected Map<CharSequence, Object> populateAnnotationData(T originatingElement, boolean originatingElementIsSameParent, A annotationMirror, DefaultAnnotationMetadata metadata, boolean isDeclared, RetentionPolicy retentionPolicy, boolean allowAliases) {
String annotationName = getAnnotationTypeName(annotationMirror);
if (retentionPolicy == RetentionPolicy.RUNTIME) {
processAnnotationDefaults(originatingElement, metadata, annotationName, () -> readAnnotationDefaultValues(annotationMirror));
}
List<String> parentAnnotations = new ArrayList<>();
parentAnnotations.add(annotationName);
Map<? extends T, ?> elementValues = readAnnotationRawValues(annotationMirror);
Map<CharSequence, Object> annotationValues;
if (CollectionUtils.isEmpty(elementValues)) {
annotationValues = new LinkedHashMap<>(3);
} else {
annotationValues = new LinkedHashMap<>(5);
Set<String> nonBindingMembers = new HashSet<>(2);
for (Map.Entry<? extends T, ?> entry : elementValues.entrySet()) {
T member = entry.getKey();
if (member == null) {
continue;
}
Object annotationValue = entry.getValue();
if (hasAnnotations(member)) {
final DefaultAnnotationMetadata memberMetadata = new DefaultAnnotationMetadata();
final List<? extends A> annotationsForMember = getAnnotationsForType(member).stream().filter((a) -> !getAnnotationTypeName(a).equals(annotationName)).collect(Collectors.toList());
includeAnnotations(memberMetadata, member, false, true, annotationsForMember, false);
boolean isInstantiatedMember = memberMetadata.hasAnnotation(InstantiatedMember.class);
if (memberMetadata.hasAnnotation(NonBinding.class)) {
final String memberName = getElementName(member);
nonBindingMembers.add(memberName);
}
if (isInstantiatedMember) {
final String memberName = getAnnotationMemberName(member);
final Object rawValue = readAnnotationValue(originatingElement, member, memberName, annotationValue);
if (rawValue instanceof AnnotationClassValue) {
AnnotationClassValue acv = (AnnotationClassValue) rawValue;
annotationValues.put(memberName, new AnnotationClassValue(acv.getName(), true));
}
}
}
if (allowAliases) {
handleAnnotationAlias(originatingElement, metadata, isDeclared, annotationName, parentAnnotations, annotationValues, member, annotationValue);
}
}
if (!nonBindingMembers.isEmpty()) {
T annotationType = getTypeForAnnotation(annotationMirror);
if (hasAnnotation(annotationType, AnnotationUtil.QUALIFIER) || hasAnnotation(annotationType, Qualifier.class)) {
metadata.addDeclaredStereotype(Collections.singletonList(getAnnotationTypeName(annotationMirror)), AnnotationUtil.QUALIFIER, Collections.singletonMap("nonBinding", nonBindingMembers));
}
}
}
List<AnnotationMapper<?>> mappers = getAnnotationMappers(annotationName);
if (mappers != null) {
AnnotationValue<?> annotationValue = new AnnotationValue(annotationName, annotationValues);
VisitorContext visitorContext = createVisitorContext();
for (AnnotationMapper mapper : mappers) {
List mapped = mapper.map(annotationValue, visitorContext);
if (mapped != null) {
for (Object o : mapped) {
if (o instanceof AnnotationValue) {
AnnotationValue av = (AnnotationValue) o;
retentionPolicy = av.getRetentionPolicy();
String mappedAnnotationName = av.getAnnotationName();
Optional<T> mappedMirror = getAnnotationMirror(mappedAnnotationName);
String repeatableName = mappedMirror.map(this::getRepeatableNameForType).orElse(null);
if (repeatableName != null) {
if (isDeclared) {
metadata.addDeclaredRepeatable(repeatableName, av, retentionPolicy);
} else {
metadata.addRepeatable(repeatableName, av, retentionPolicy);
}
} else {
Map<CharSequence, Object> values = av.getValues();
if (isDeclared) {
metadata.addDeclaredAnnotation(mappedAnnotationName, values, retentionPolicy);
} else {
metadata.addAnnotation(mappedAnnotationName, values, retentionPolicy);
}
}
RetentionPolicy finalRetentionPolicy = retentionPolicy;
mappedMirror.ifPresent(annMirror -> {
Map<CharSequence, Object> values = av.getValues();
values.forEach((key, value) -> {
T member = getAnnotationMember(annMirror, key);
if (member != null) {
handleAnnotationAlias(originatingElement, metadata, isDeclared, mappedAnnotationName, Collections.emptyList(), annotationValues, member, value);
}
});
if (finalRetentionPolicy == RetentionPolicy.RUNTIME) {
processAnnotationDefaults(originatingElement, metadata, mappedAnnotationName, () -> readAnnotationDefaultValues(mappedAnnotationName, annMirror));
}
final ArrayList<String> parents = new ArrayList<>();
processAnnotationStereotype(parents, annMirror, mappedAnnotationName, metadata, isDeclared, isInheritedAnnotationType(annMirror) || originatingElementIsSameParent);
});
}
}
}
}
}
return annotationValues;
}
use of io.micronaut.inject.visitor.VisitorContext in project micronaut-core by micronaut-projects.
the class GraalTypeElementVisitor method generateNativeImageProperties.
private void generateNativeImageProperties(VisitorContext visitorContext) {
List<Map> json;
Optional<Path> projectDir = visitorContext.getProjectDir();
File userReflectJsonFile = projectDir.map(projectPath -> Paths.get(projectPath.toString(), BASE_REFLECT_JSON).toFile()).orElse(null);
if (userReflectJsonFile != null && userReflectJsonFile.exists()) {
try {
json = MAPPER.readValue(userReflectJsonFile, new TypeReference<List<Map>>() {
});
} catch (Throwable e) {
visitorContext.fail("Error parsing base reflect.json: " + BASE_REFLECT_JSON, null);
return;
}
} else {
json = new ArrayList<>();
}
if (CollectionUtils.isEmpty(classes) && CollectionUtils.isEmpty(arrays) && CollectionUtils.isEmpty(json)) {
return;
}
try {
String path = buildNativeImagePath(visitorContext);
String reflectFile = path + REFLECTION_CONFIG_JSON;
final Optional<GeneratedFile> generatedFile = visitorContext.visitMetaInfFile(reflectFile, originatingElements.toArray(Element.EMPTY_ELEMENT_ARRAY));
generatedFile.ifPresent(gf -> {
for (Map<String, Object> value : classes.values()) {
json.add(value);
}
for (String array : arrays) {
json.add(CollectionUtils.mapOf(NAME, "[L" + array.substring(0, array.length() - 2) + ";", ALL_DECLARED_CONSTRUCTORS, true));
}
ObjectWriter writer = MAPPER.writer(new DefaultPrettyPrinter());
try (Writer w = gf.openWriter()) {
visitorContext.info("Writing " + REFLECTION_CONFIG_JSON + " file to destination: " + gf.getName());
writer.writeValue(w, json);
} catch (IOException e) {
visitorContext.fail("Error writing " + REFLECTION_CONFIG_JSON + ": " + e.getMessage(), null);
}
});
} finally {
packages.clear();
classes.clear();
arrays.clear();
originatingElements.clear();
}
}
use of io.micronaut.inject.visitor.VisitorContext in project micronaut-core by micronaut-projects.
the class GraalTypeElementVisitor method visitClass.
@Override
public void visitClass(ClassElement element, VisitorContext context) {
if (!isSubclass && !element.hasStereotype(Deprecated.class)) {
if (element.hasAnnotation(ReflectiveAccess.class)) {
originatingElements.add(element);
packages.add(element.getPackageName());
final String beanName = element.getName();
addBean(beanName);
resolveClassData(beanName + "[]");
}
if (element.hasAnnotation(TypeHint.class)) {
originatingElements.add(element);
packages.add(element.getPackageName());
final String[] introspectedClasses = element.stringValues(TypeHint.class);
final TypeHint typeHint = element.synthesize(TypeHint.class);
TypeHint.AccessType[] accessTypes = DEFAULT_ACCESS_TYPE;
if (typeHint != null) {
accessTypes = typeHint.accessType();
}
processClasses(accessTypes, introspectedClasses);
processClasses(accessTypes, element.getValue(TypeHint.class, "typeNames", String[].class).orElse(StringUtils.EMPTY_STRING_ARRAY));
}
if (element.hasAnnotation(Import.class)) {
final List<ClassElement> beanElements = BeanImportVisitor.collectInjectableElements(element, context);
for (ClassElement beanElement : beanElements) {
final MethodElement constructor = beanElement.getPrimaryConstructor().orElse(null);
if (constructor != null && !constructor.isPublic()) {
processMethodElement(constructor);
}
final ElementQuery<MethodElement> reflectiveMethodQuery = ElementQuery.ALL_METHODS.onlyInstance().onlyConcrete().onlyInjected().modifiers((elementModifiers -> !elementModifiers.contains(ElementModifier.PUBLIC)));
final List<MethodElement> reflectiveMethods = beanElement.getEnclosedElements(reflectiveMethodQuery);
reflectiveMethods.forEach(this::processMethodElement);
final ElementQuery<FieldElement> reflectiveFieldQuery = ElementQuery.ALL_FIELDS.onlyInstance().onlyInjected().modifiers((elementModifiers -> !elementModifiers.contains(ElementModifier.PUBLIC)));
final List<FieldElement> reflectiveFields = beanElement.getEnclosedElements(reflectiveFieldQuery);
reflectiveFields.forEach(this::processFieldElement);
}
} else if (element.hasStereotype(Bean.class) || element.hasStereotype(AnnotationUtil.SCOPE) || element.hasStereotype(AnnotationUtil.QUALIFIER)) {
MethodElement me = element.getPrimaryConstructor().orElse(null);
if (me != null && me.isPrivate() && !me.hasAnnotation(ReflectiveAccess.class)) {
processMethodElement(me);
}
}
if (element.isInner()) {
ClassElement enclosingType = element.getEnclosingType().orElse(null);
if (enclosingType != null && enclosingType.hasAnnotation(ReflectiveAccess.class)) {
originatingElements.add(enclosingType);
packages.add(enclosingType.getPackageName());
final String beanName = element.getName();
addBean(beanName);
resolveClassData(beanName + "[]");
}
}
}
}
use of io.micronaut.inject.visitor.VisitorContext in project micronaut-core by micronaut-projects.
the class AbstractAnnotationMetadataBuilder method remapAnnotation.
private List<AnnotationValue<?>> remapAnnotation(String annotationName) {
String packageName = NameUtils.getPackageName(annotationName);
List<AnnotationRemapper> annotationRemappers = ANNOTATION_REMAPPERS.get(packageName);
List<AnnotationValue<?>> mappedAnnotations = new ArrayList<>();
if (annotationRemappers == null || annotationRemappers.isEmpty()) {
mappedAnnotations.add(AnnotationValue.builder(annotationName).build());
return mappedAnnotations;
}
VisitorContext visitorContext = createVisitorContext();
io.micronaut.core.annotation.AnnotationValue<?> av = new AnnotationValue<>(annotationName);
for (AnnotationRemapper annotationRemapper : annotationRemappers) {
List<AnnotationValue<?>> remappedValues = annotationRemapper.remap(av, visitorContext);
if (CollectionUtils.isNotEmpty(remappedValues)) {
for (AnnotationValue<?> annotationValue : remappedValues) {
if (annotationValue == av && remappedValues.size() == 1) {
// bail, the re-mapper just returned the same annotation
break;
} else {
mappedAnnotations.add(annotationValue);
}
}
}
}
return mappedAnnotations;
}
Aggregations