Search in sources :

Example 1 with PropertyMetadata

use of org.gradle.internal.reflect.PropertyMetadata 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));
                }
            });
        }
    }
}
Also used : TypeMetadata(org.gradle.api.internal.tasks.properties.TypeMetadata) PropertyAnnotationHandler(org.gradle.api.internal.tasks.properties.annotations.PropertyAnnotationHandler) BeanPropertyContext(org.gradle.api.internal.tasks.properties.BeanPropertyContext) PropertyMetadata(org.gradle.internal.reflect.PropertyMetadata) PropertyValue(org.gradle.api.internal.tasks.properties.PropertyValue)

Example 2 with PropertyMetadata

use of org.gradle.internal.reflect.PropertyMetadata in project gradle by gradle.

the class DefaultTransformationRegistrationFactory method create.

@Override
public ArtifactTransformRegistration create(ImmutableAttributes from, ImmutableAttributes to, Class<? extends TransformAction<?>> implementation, @Nullable TransformParameters parameterObject) {
    TypeMetadata actionMetadata = actionMetadataStore.getTypeMetadata(implementation);
    boolean cacheable = implementation.isAnnotationPresent(CacheableTransform.class);
    DefaultTypeValidationContext validationContext = DefaultTypeValidationContext.withoutRootType(documentationRegistry, cacheable);
    actionMetadata.visitValidationFailures(null, validationContext);
    // Should retain this on the metadata rather than calculate on each invocation
    Class<? extends FileNormalizer> inputArtifactNormalizer = null;
    Class<? extends FileNormalizer> dependenciesNormalizer = null;
    DirectorySensitivity artifactDirectorySensitivity = DirectorySensitivity.DEFAULT;
    DirectorySensitivity dependenciesDirectorySensitivity = DirectorySensitivity.DEFAULT;
    LineEndingSensitivity artifactLineEndingSensitivity = LineEndingSensitivity.DEFAULT;
    LineEndingSensitivity dependenciesLineEndingSensitivity = LineEndingSensitivity.DEFAULT;
    for (PropertyMetadata propertyMetadata : actionMetadata.getPropertiesMetadata()) {
        Class<? extends Annotation> propertyType = propertyMetadata.getPropertyType();
        if (propertyType.equals(InputArtifact.class)) {
            // Should ask the annotation handler to figure this out instead
            NormalizerCollectingVisitor visitor = new NormalizerCollectingVisitor();
            actionMetadata.getAnnotationHandlerFor(propertyMetadata).visitPropertyValue(propertyMetadata.getPropertyName(), null, propertyMetadata, visitor, null);
            inputArtifactNormalizer = visitor.normalizer;
            artifactDirectorySensitivity = visitor.directorySensitivity;
            artifactLineEndingSensitivity = visitor.lineEndingSensitivity;
            DefaultTransformer.validateInputFileNormalizer(propertyMetadata.getPropertyName(), inputArtifactNormalizer, cacheable, validationContext);
        } else if (propertyType.equals(InputArtifactDependencies.class)) {
            NormalizerCollectingVisitor visitor = new NormalizerCollectingVisitor();
            actionMetadata.getAnnotationHandlerFor(propertyMetadata).visitPropertyValue(propertyMetadata.getPropertyName(), null, propertyMetadata, visitor, null);
            dependenciesNormalizer = visitor.normalizer;
            dependenciesDirectorySensitivity = visitor.directorySensitivity;
            dependenciesLineEndingSensitivity = visitor.lineEndingSensitivity;
            DefaultTransformer.validateInputFileNormalizer(propertyMetadata.getPropertyName(), dependenciesNormalizer, cacheable, validationContext);
        }
    }
    ImmutableMap<String, Severity> validationMessages = validationContext.getProblems();
    if (!validationMessages.isEmpty()) {
        String formatString = validationMessages.size() == 1 ? "A problem was found with the configuration of %s." : "Some problems were found with the configuration of %s.";
        throw new DefaultMultiCauseException(String.format(formatString, ModelType.of(implementation).getDisplayName()), validationMessages.keySet().stream().sorted().map(InvalidUserDataException::new).collect(Collectors.toList()));
    }
    Transformer transformer = new DefaultTransformer(implementation, parameterObject, from, FileParameterUtils.normalizerOrDefault(inputArtifactNormalizer), FileParameterUtils.normalizerOrDefault(dependenciesNormalizer), cacheable, artifactDirectorySensitivity, dependenciesDirectorySensitivity, artifactLineEndingSensitivity, dependenciesLineEndingSensitivity, buildOperationExecutor, classLoaderHierarchyHasher, isolatableFactory, fileCollectionFactory, fileLookup, parametersPropertyWalker, actionInstantiationScheme, owner, calculatedValueContainerFactory, internalServices, documentationRegistry);
    return new DefaultArtifactTransformRegistration(from, to, new TransformationStep(transformer, transformerInvocationFactory, owner, inputFingerprinter));
}
Also used : LineEndingSensitivity(org.gradle.internal.fingerprint.LineEndingSensitivity) TypeMetadata(org.gradle.api.internal.tasks.properties.TypeMetadata) InputArtifactDependencies(org.gradle.api.artifacts.transform.InputArtifactDependencies) DirectorySensitivity(org.gradle.internal.fingerprint.DirectorySensitivity) Severity(org.gradle.internal.reflect.validation.Severity) DefaultMultiCauseException(org.gradle.internal.exceptions.DefaultMultiCauseException) InvalidUserDataException(org.gradle.api.InvalidUserDataException) DefaultTypeValidationContext(org.gradle.internal.reflect.DefaultTypeValidationContext) PropertyMetadata(org.gradle.internal.reflect.PropertyMetadata)

Example 3 with PropertyMetadata

use of org.gradle.internal.reflect.PropertyMetadata 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);
}
Also used : TypeAnnotationMetadata(org.gradle.internal.reflect.annotations.TypeAnnotationMetadata) AbstractOutputPropertyAnnotationHandler(org.gradle.api.internal.tasks.properties.annotations.AbstractOutputPropertyAnnotationHandler) TypeAnnotationHandler(org.gradle.api.internal.tasks.properties.annotations.TypeAnnotationHandler) InputFiles(org.gradle.api.tasks.InputFiles) Function(java.util.function.Function) NORMALIZATION(org.gradle.api.internal.tasks.properties.ModifierAnnotationCategory.NORMALIZATION) PropertyAnnotationHandler(org.gradle.api.internal.tasks.properties.annotations.PropertyAnnotationHandler) Map(java.util.Map) TYPE(org.gradle.internal.reflect.AnnotationCategory.TYPE) Collector(java.util.stream.Collector) Method(java.lang.reflect.Method) Nullable(javax.annotation.Nullable) GeneratedSubclasses(org.gradle.api.internal.GeneratedSubclasses) Classpath(org.gradle.api.tasks.Classpath) ImmutableSet(com.google.common.collect.ImmutableSet) CompileClasspath(org.gradle.api.tasks.CompileClasspath) ImmutableMap(com.google.common.collect.ImmutableMap) Collection(java.util.Collection) ReplayingTypeValidationContext(org.gradle.internal.reflect.validation.ReplayingTypeValidationContext) Set(java.util.Set) AnnotationCategory(org.gradle.internal.reflect.AnnotationCategory) TypeValidationContext(org.gradle.internal.reflect.validation.TypeValidationContext) CrossBuildInMemoryCache(org.gradle.cache.internal.CrossBuildInMemoryCache) Maps(com.google.common.collect.Maps) Collectors(java.util.stream.Collectors) TypeAnnotationMetadataStore(org.gradle.internal.reflect.annotations.TypeAnnotationMetadataStore) PropertyMetadata(org.gradle.internal.reflect.PropertyMetadata) PropertyAnnotationMetadata(org.gradle.internal.reflect.annotations.PropertyAnnotationMetadata) ERROR(org.gradle.internal.reflect.validation.Severity.ERROR) Annotation(java.lang.annotation.Annotation) CrossBuildInMemoryCacheFactory(org.gradle.cache.internal.CrossBuildInMemoryCacheFactory) ValidationProblemId(org.gradle.internal.reflect.problems.ValidationProblemId) AbstractOutputPropertyAnnotationHandler(org.gradle.api.internal.tasks.properties.annotations.AbstractOutputPropertyAnnotationHandler) PropertyAnnotationHandler(org.gradle.api.internal.tasks.properties.annotations.PropertyAnnotationHandler) TypeAnnotationHandler(org.gradle.api.internal.tasks.properties.annotations.TypeAnnotationHandler) PropertyAnnotationMetadata(org.gradle.internal.reflect.annotations.PropertyAnnotationMetadata) ReplayingTypeValidationContext(org.gradle.internal.reflect.validation.ReplayingTypeValidationContext) AnnotationCategory(org.gradle.internal.reflect.AnnotationCategory) Annotation(java.lang.annotation.Annotation) ImmutableSet(com.google.common.collect.ImmutableSet) PropertyMetadata(org.gradle.internal.reflect.PropertyMetadata) TypeAnnotationMetadata(org.gradle.internal.reflect.annotations.TypeAnnotationMetadata) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap)

Aggregations

PropertyMetadata (org.gradle.internal.reflect.PropertyMetadata)3 TypeMetadata (org.gradle.api.internal.tasks.properties.TypeMetadata)2 PropertyAnnotationHandler (org.gradle.api.internal.tasks.properties.annotations.PropertyAnnotationHandler)2 ImmutableMap (com.google.common.collect.ImmutableMap)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 Maps (com.google.common.collect.Maps)1 Annotation (java.lang.annotation.Annotation)1 Method (java.lang.reflect.Method)1 Collection (java.util.Collection)1 Map (java.util.Map)1 Set (java.util.Set)1 Function (java.util.function.Function)1 Collector (java.util.stream.Collector)1 Collectors (java.util.stream.Collectors)1 Nullable (javax.annotation.Nullable)1 InvalidUserDataException (org.gradle.api.InvalidUserDataException)1 InputArtifactDependencies (org.gradle.api.artifacts.transform.InputArtifactDependencies)1 GeneratedSubclasses (org.gradle.api.internal.GeneratedSubclasses)1 BeanPropertyContext (org.gradle.api.internal.tasks.properties.BeanPropertyContext)1 NORMALIZATION (org.gradle.api.internal.tasks.properties.ModifierAnnotationCategory.NORMALIZATION)1