All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.micronaut.inject.annotation.AbstractEnvironmentAnnotationMetadata Maven / Gradle / Ivy

/*
 * Copyright 2017-2019 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
 *
 * http://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.env.Environment;
import io.micronaut.core.annotation.AnnotationMetadata;
import io.micronaut.core.annotation.AnnotationValue;
import io.micronaut.core.annotation.Internal;
import io.micronaut.core.type.Argument;
import io.micronaut.core.util.ArgumentUtils;
import io.micronaut.core.util.StringUtils;
import io.micronaut.core.value.OptionalValues;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Variation of {@link AnnotationMetadata} that is environment specific.
 *
 * @author Graeme Rocher
 * @since 1.0
 */
@Internal
public abstract class AbstractEnvironmentAnnotationMetadata extends AbstractAnnotationMetadata implements AnnotationMetadata {

    private final DefaultAnnotationMetadata annotationMetadata;

    /**
     * Construct a new environment aware annotation metadata.
     *
     * @param targetMetadata The target annotation metadata
     */
    protected AbstractEnvironmentAnnotationMetadata(DefaultAnnotationMetadata targetMetadata) {
        super(targetMetadata.declaredAnnotations, targetMetadata.allAnnotations);
        this.annotationMetadata = targetMetadata;
    }

    @Override
    public @Nonnull Optional> getAnnotationType(@Nonnull String name) {
        ArgumentUtils.requireNonNull("name", name);
        return annotationMetadata.getAnnotationType(name);
    }

    @Override
    public @Nonnull  List> getAnnotationValuesByType(@Nonnull Class annotationType) {
        ArgumentUtils.requireNonNull("annotationType", annotationType);
        Environment environment = getEnvironment();
        List> values = annotationMetadata.getAnnotationValuesByType(annotationType);
        if (environment != null) {
            return values.stream().map(entries ->
                    new EnvironmentAnnotationValue(environment, entries)
            ).collect(Collectors.toList());
        }
        return values;
    }

    @Override
    public @Nonnull  List> getDeclaredAnnotationValuesByType(@Nonnull Class annotationType) {
        ArgumentUtils.requireNonNull("annotationType", annotationType);
        Environment environment = getEnvironment();
        List> values = annotationMetadata.getDeclaredAnnotationValuesByType(annotationType);
        if (environment != null) {
            return values.stream().map(entries -> new EnvironmentAnnotationValue(environment, entries))
                    .collect(Collectors.toList());
        }
        return values;
    }

    @SuppressWarnings("unchecked")
    @Override
    public @Nonnull  T[] synthesizeAnnotationsByType(@Nonnull Class annotationClass) {
        ArgumentUtils.requireNonNull("annotationClass", annotationClass);
        Environment environment = getEnvironment();
        if (environment != null) {

            List> values = annotationMetadata.getAnnotationValuesByType(annotationClass);

            return values.stream()
                    .map(entries -> AnnotationMetadataSupport.buildAnnotation(annotationClass, EnvironmentConvertibleValuesMap.of(environment, entries.getValues())))
                    .toArray(value -> (T[]) Array.newInstance(annotationClass, value));
        } else {
            return annotationMetadata.synthesizeAnnotationsByType(annotationClass);
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    public @Nonnull  T[] synthesizeDeclaredAnnotationsByType(@Nonnull Class annotationClass) {
        ArgumentUtils.requireNonNull("annotationClass", annotationClass);
        Environment environment = getEnvironment();
        if (environment != null) {

            List> values = annotationMetadata.getDeclaredAnnotationValuesByType(annotationClass);

            return values.stream()
                    .map(entries -> AnnotationMetadataSupport.buildAnnotation(annotationClass, EnvironmentConvertibleValuesMap.of(environment, entries.getValues())))
                    .toArray(value -> (T[]) Array.newInstance(annotationClass, value));
        } else {
            return annotationMetadata.synthesizeDeclaredAnnotationsByType(annotationClass);
        }
    }

    @Override
    public boolean hasDeclaredAnnotation(@Nullable String annotation) {
        return annotationMetadata.hasDeclaredAnnotation(annotation);
    }

    @Override
    public boolean hasAnnotation(@Nullable String annotation) {
        return annotationMetadata.hasAnnotation(annotation);
    }

    @Override
    public boolean hasStereotype(@Nullable String annotation) {
        return annotationMetadata.hasStereotype(annotation);
    }

    @Override
    public boolean hasDeclaredStereotype(@Nullable String annotation) {
        return annotationMetadata.hasDeclaredStereotype(annotation);
    }

    @Override
    public @Nonnull List getAnnotationNamesByStereotype(String stereotype) {
        return annotationMetadata.getAnnotationNamesByStereotype(stereotype);
    }

    @Override
    public @Nonnull Set getAnnotationNames() {
        return annotationMetadata.getAnnotationNames();
    }

    @Override
    public @Nonnull Set getDeclaredAnnotationNames() {
        return annotationMetadata.getDeclaredAnnotationNames();
    }

    @Override
    public @Nonnull List getDeclaredAnnotationNamesByStereotype(String stereotype) {
        return annotationMetadata.getDeclaredAnnotationNamesByStereotype(stereotype);
    }

    @Override
    public @Nonnull  Optional> findAnnotation(@Nonnull String annotation) {
        ArgumentUtils.requireNonNull("annotation", annotation);
        Environment env = getEnvironment();

        Optional> values = annotationMetadata.findAnnotation(annotation);

        if (env != null) {
            return values.map(av -> new EnvironmentAnnotationValue<>(env, av));
        }
        return values;
    }

    @Override
    public @Nonnull  Optional> findDeclaredAnnotation(@Nonnull String annotation) {
        ArgumentUtils.requireNonNull("annotation", annotation);
        Environment env = getEnvironment();

        Optional> values = annotationMetadata.findDeclaredAnnotation(annotation);

        if (env != null) {
            return values.map(av -> new EnvironmentAnnotationValue<>(env, av));
        }
        return values;
    }

    @Override
    public @Nonnull  OptionalValues getValues(@Nonnull String annotation, @Nonnull Class valueType) {
        ArgumentUtils.requireNonNull("annotation", annotation);
        ArgumentUtils.requireNonNull("valueType", valueType);
        Map> allAnnotations = annotationMetadata.allAnnotations;
        Map> allStereotypes = annotationMetadata.allStereotypes;
        Environment environment = getEnvironment();
        OptionalValues values = resolveOptionalValuesForEnvironment(annotation, valueType, allAnnotations, allStereotypes, environment);
        if (values != null) {
            return values;
        }
        return OptionalValues.empty();
    }

    @Override
    public @Nonnull  Optional getDefaultValue(@Nonnull String annotation, @Nonnull String member, @Nonnull Class requiredType) {
        return annotationMetadata.getDefaultValue(annotation, member, requiredType);
    }

    @Override
    public @Nonnull  Optional getDefaultValue(@Nonnull String annotation, @Nonnull String member, @Nonnull Argument requiredType) {
        return annotationMetadata.getDefaultValue(annotation, member, requiredType);
    }

    /**
     * Resolves the {@link Environment} for this metadata.
     *
     * @return The metadata
     */
    protected abstract @Nullable Environment getEnvironment();

    @Override
    protected void addValuesToResults(List results, AnnotationValue values) {
        Environment environment = getEnvironment();
        if (environment != null) {
            results.add(new EnvironmentAnnotationValue(environment, values));
        } else {
            results.add(values);
        }
    }

    private  OptionalValues resolveOptionalValuesForEnvironment(String annotation, Class valueType, Map> allAnnotations, Map> allStereotypes, Environment environment) {
        if (allAnnotations != null && StringUtils.isNotEmpty(annotation)) {
            Map values = allAnnotations.get(annotation);
            if (values != null) {
                if (environment != null) {
                    return new EnvironmentOptionalValuesMap<>(valueType, values, environment);
                } else {
                    return OptionalValues.of(valueType, values);
                }
            } else {
                values = allStereotypes.get(annotation);
                if (values != null) {
                    if (environment != null) {
                        return new EnvironmentOptionalValuesMap<>(valueType, values, environment);
                    } else {
                        return OptionalValues.of(valueType, values);
                    }
                }
            }
        }
        return null;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy