use of org.gradle.api.internal.tasks.properties.annotations.PropertyAnnotationHandler in project gradle by gradle.
the class AbstractNestedRuntimeBeanNode method visitProperties.
protected void visitProperties(PropertyVisitor visitor, final Queue<RuntimeBeanNode<?>> queue, final RuntimeBeanNodeFactory nodeFactory, TypeValidationContext validationContext) {
TypeMetadata typeMetadata = getTypeMetadata();
typeMetadata.visitValidationFailures(getPropertyName(), validationContext);
for (PropertyMetadata propertyMetadata : typeMetadata.getPropertiesMetadata()) {
PropertyAnnotationHandler annotationHandler = typeMetadata.getAnnotationHandlerFor(propertyMetadata);
if (annotationHandler.shouldVisit(visitor)) {
String propertyName = getQualifiedPropertyName(propertyMetadata.getPropertyName());
PropertyValue value = new BeanPropertyValue(getBean(), propertyMetadata.getGetterMethod());
annotationHandler.visitPropertyValue(propertyName, value, propertyMetadata, visitor, new BeanPropertyContext() {
@Override
public void addNested(String propertyName, Object bean) {
queue.add(nodeFactory.create(AbstractNestedRuntimeBeanNode.this, propertyName, bean));
}
});
}
}
}
use of org.gradle.api.internal.tasks.properties.annotations.PropertyAnnotationHandler in project gradle by gradle.
the class InspectionSchemeFactory method inspectionScheme.
/**
* Creates a new {@link InspectionScheme} with the given annotations enabled and using the given instantiation scheme.
*/
public InspectionScheme inspectionScheme(Collection<Class<? extends Annotation>> annotations, Collection<Class<? extends Annotation>> propertyModifiers, InstantiationScheme instantiationScheme) {
ImmutableList.Builder<PropertyAnnotationHandler> propertyHandlers = ImmutableList.builderWithExpectedSize(annotations.size());
for (Class<? extends Annotation> annotation : annotations) {
PropertyAnnotationHandler propertyHandler = allKnownPropertyHandlers.get(annotation);
if (propertyHandler == null) {
throw new IllegalArgumentException(String.format("@%s is not a registered property type annotation.", annotation.getSimpleName()));
}
propertyHandlers.add(propertyHandler);
}
for (Class<? extends Annotation> annotation : instantiationScheme.getInjectionAnnotations()) {
if (!annotations.contains(annotation)) {
propertyHandlers.add(new NoOpPropertyAnnotationHandler(annotation));
}
}
return new InspectionSchemeImpl(allKnownTypeHandlers, propertyHandlers.build(), propertyModifiers, typeAnnotationMetadataStore, cacheFactory);
}
use of org.gradle.api.internal.tasks.properties.annotations.PropertyAnnotationHandler in project gradle by gradle.
the class DefaultTypeMetadataStore method createTypeMetadata.
private <T> TypeMetadata createTypeMetadata(Class<T> type) {
Class<?> publicType = GeneratedSubclasses.unpack(type);
ReplayingTypeValidationContext validationContext = new ReplayingTypeValidationContext();
TypeAnnotationMetadata annotationMetadata = typeAnnotationMetadataStore.getTypeAnnotationMetadata(publicType);
annotationMetadata.visitValidationFailures(validationContext);
for (TypeAnnotationHandler annotationHandler : typeAnnotationHandlers) {
if (annotationMetadata.isAnnotationPresent(annotationHandler.getAnnotationType())) {
annotationHandler.validateTypeMetadata(publicType, validationContext);
}
}
ImmutableSet.Builder<PropertyMetadata> effectiveProperties = ImmutableSet.builderWithExpectedSize(annotationMetadata.getPropertiesAnnotationMetadata().size());
for (PropertyAnnotationMetadata propertyAnnotationMetadata : annotationMetadata.getPropertiesAnnotationMetadata()) {
Map<AnnotationCategory, Annotation> propertyAnnotations = propertyAnnotationMetadata.getAnnotations();
Annotation typeAnnotation = propertyAnnotations.get(TYPE);
Annotation normalizationAnnotation = propertyAnnotations.get(NORMALIZATION);
Class<? extends Annotation> propertyType = determinePropertyType(typeAnnotation, normalizationAnnotation);
if (propertyType == null) {
validationContext.visitPropertyProblem(problem -> problem.withId(ValidationProblemId.MISSING_ANNOTATION).forProperty(propertyAnnotationMetadata.getPropertyName()).reportAs(ERROR).withDescription(() -> "is missing " + displayName).happensBecause("A property without annotation isn't considered during up-to-date checking").addPossibleSolution(() -> "Add " + displayName).addPossibleSolution("Mark it as @Internal").documentedAt("validation_problems", "missing_annotation"));
continue;
}
PropertyAnnotationHandler annotationHandler = propertyAnnotationHandlers.get(propertyType);
if (annotationHandler == null) {
validationContext.visitPropertyProblem(problem -> problem.withId(ValidationProblemId.ANNOTATION_INVALID_IN_CONTEXT).forProperty(propertyAnnotationMetadata.getPropertyName()).reportAs(ERROR).withDescription(() -> String.format("is annotated with invalid property type @%s", propertyType.getSimpleName())).happensBecause(() -> "The '@" + propertyType.getSimpleName() + "' annotation cannot be used in this context").addPossibleSolution("Remove the property").addPossibleSolution(() -> "Use a different annotation, e.g one of " + toListOfAnnotations(propertyAnnotationHandlers.keySet())).documentedAt("validation_problems", "annotation_invalid_in_context"));
continue;
}
ImmutableSet<? extends AnnotationCategory> allowedModifiersForPropertyType = annotationHandler.getAllowedModifiers();
for (Map.Entry<AnnotationCategory, Annotation> entry : propertyAnnotations.entrySet()) {
AnnotationCategory annotationCategory = entry.getKey();
if (annotationCategory == TYPE) {
continue;
}
Class<? extends Annotation> annotationType = entry.getValue().annotationType();
if (!allowedModifiersForPropertyType.contains(annotationCategory)) {
validationContext.visitPropertyProblem(problem -> problem.withId(ValidationProblemId.INCOMPATIBLE_ANNOTATIONS).forProperty(propertyAnnotationMetadata.getPropertyName()).reportAs(ERROR).withDescription(() -> "is annotated with @" + annotationType.getSimpleName() + " but that is not allowed for '" + propertyType.getSimpleName() + "' properties").happensBecause(() -> "This modifier is used in conjunction with a property of type '" + propertyType.getSimpleName() + "' but this doesn't have semantics").withLongDescription(() -> "The list of allowed modifiers for '" + propertyType.getSimpleName() + "' is " + toListOfAnnotations(allowedPropertyModifiers)).addPossibleSolution(() -> "Remove the '@" + annotationType.getSimpleName() + "' annotation").documentedAt("validation_problems", "incompatible_annotations"));
} else if (!allowedPropertyModifiers.contains(annotationType)) {
validationContext.visitPropertyProblem(problem -> problem.withId(ValidationProblemId.ANNOTATION_INVALID_IN_CONTEXT).forProperty(propertyAnnotationMetadata.getPropertyName()).reportAs(ERROR).withDescription(() -> String.format("is annotated with invalid modifier @%s", annotationType.getSimpleName())).happensBecause(() -> "The '@" + annotationType.getSimpleName() + "' annotation cannot be used in this context").addPossibleSolution("Remove the annotation").addPossibleSolution(() -> "Use a different annotation, e.g one of " + toListOfAnnotations(allowedPropertyModifiers)).documentedAt("validation_problems", "annotation_invalid_in_context"));
}
}
PropertyMetadata property = new DefaultPropertyMetadata(propertyType, propertyAnnotationMetadata);
annotationHandler.validatePropertyMetadata(property, validationContext);
if (annotationHandler.isPropertyRelevant()) {
effectiveProperties.add(property);
}
}
return new DefaultTypeMetadata(effectiveProperties.build(), validationContext, propertyAnnotationHandlers);
}
use of org.gradle.api.internal.tasks.properties.annotations.PropertyAnnotationHandler in project gradle by gradle.
the class ValidationServicesFixture method getServices.
public static ServiceRegistry getServices() {
DefaultServiceRegistry registry = new DefaultServiceRegistry();
registry.addProvider(new Object() {
ExecutionGlobalServices.AnnotationHandlerRegistration createAnnotationRegistration() {
return () -> ImmutableList.of(ValidationProblem.class);
}
PropertyAnnotationHandler createValidationProblemAnnotationHandler() {
return new ValidationProblemPropertyAnnotationHandler();
}
});
return registry;
}
Aggregations