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

fi.jubic.easyconfig.internal.ConfigPropertyDef Maven / Gradle / Ivy

There is a newer version: 0.10.4
Show newest version
package fi.jubic.easyconfig.internal;

import fi.jubic.easyconfig.annotations.ConfigProperty;
import fi.jubic.easyconfig.annotations.EasyConfigProperty;
import fi.jubic.easyconfig.annotations.EnvProviderProperty;
import fi.jubic.easyconfig.extensions.ConfigExtension;
import fi.jubic.easyconfig.extensions.ConfigExtensionProvider;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Parameter;
import java.lang.reflect.ParameterizedType;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Internal property representation for supporting the deprecated
 * {@link fi.jubic.easyconfig.annotations.EasyConfigProperty} annotation.
 */
@SuppressWarnings("deprecation")
public class ConfigPropertyDef {
    private final String variableName;
    private final String defaultValue;
    private final String listDelimiter;
    private final boolean nullable;
    private final boolean noPrefix;

    private final Class propertyClass;
    private final List> typeArguments;
    private final AnnotatedElement annotatedElement;

    private ConfigPropertyDef(
            EasyConfigProperty property,
            Class propertyClass,
            List> typeArguments,
            AnnotatedElement annotatedElement
    ) {
        this.variableName = property.value();
        this.defaultValue = parseDefaultValue(property.defaultValue());
        this.listDelimiter = property.listDelimiter();
        this.nullable = false;
        this.noPrefix = false;

        this.propertyClass = propertyClass;
        this.typeArguments = Collections.unmodifiableList(typeArguments);
        this.annotatedElement = annotatedElement;
    }

    private ConfigPropertyDef(
            ConfigProperty property,
            Class propertyClass,
            List> typeArguments,
            AnnotatedElement annotatedElement
    ) {
        this.variableName = property.value();
        this.defaultValue = property.defaultValue();
        this.listDelimiter = property.listDelimiter();
        this.nullable = property.nullable();
        this.noPrefix = property.noPrefix();

        this.propertyClass = propertyClass;
        this.typeArguments = Collections.unmodifiableList(typeArguments);
        this.annotatedElement = annotatedElement;
    }

    private ConfigPropertyDef(
            Class propertyClass,
            List> typeArguments,
            AnnotatedElement annotatedElement
    ) {
        this.variableName = null;
        this.defaultValue = null;
        this.listDelimiter = null;
        this.nullable = false;
        this.noPrefix = false;

        this.propertyClass = propertyClass;
        this.typeArguments = Collections.unmodifiableList(typeArguments);
        this.annotatedElement = annotatedElement;
    }

    /**
     * Create property definition from a {@code Class}.
     *
     * @param prefix the variable namespace prefix
     * @param propertyClass the class of the property
     */
    public ConfigPropertyDef(
            String prefix,
            Class propertyClass
    ) {
        this.variableName = prefix;
        this.defaultValue = null;
        this.listDelimiter = null;
        this.nullable = false;
        this.noPrefix = false;

        this.propertyClass = propertyClass;
        this.typeArguments = Collections.emptyList();
        this.annotatedElement = null;
    }

    public static ConfigPropertyDef buildForExtensionProvider(
            Annotation annotation
    ) {
        ConfigExtension configExtension = annotation.annotationType()
                .getAnnotation(ConfigExtension.class);
        if (configExtension == null) {
            throw new IllegalStateException(
                    String.format(
                            "Invalid extension %s: %s annotation not found",
                            annotation.annotationType().getCanonicalName(),
                            ConfigExtension.class.getSimpleName()
                    )
            );
        }

        Class> providerClass
                = configExtension.value();

        return new ConfigPropertyDef(
                "",
                providerClass
        );
    }

    public static Optional buildForParameter(
            Parameter parameter,
            AnnotatedElement element
    ) {
        return Stream
                .of(
                        Optional.ofNullable(
                                element.getAnnotation(ConfigProperty.class)
                        ).map(annotation -> new ConfigPropertyDef(
                                annotation,
                                classOf(parameter),
                                typeArgsOf(parameter),
                                element
                        )),
                        Optional.ofNullable(
                                element.getAnnotation(EasyConfigProperty.class)
                        ).map(annotation -> new ConfigPropertyDef(
                                annotation,
                                classOf(parameter),
                                typeArgsOf(parameter),
                                element
                        )),
                        Optional.ofNullable(
                                element.getAnnotation(EnvProviderProperty.class)
                        ).map(annotation -> new ConfigPropertyDef(
                                classOf(parameter),
                                typeArgsOf(parameter),
                                element

                        ))
                )
                .filter(Optional::isPresent)
                .map(Optional::get)
                .findFirst();
    }

    public String getVariableName() {
        return variableName;
    }

    public Optional getDefaultValue() {
        return Optional.ofNullable(defaultValue)
                .filter(defaultValue -> !ConfigProperty.UNDEFINED_DEFAULT.equals(defaultValue));
    }

    public String getListDelimiter() {
        return listDelimiter;
    }

    public boolean isNullable() {
        return nullable;
    }

    public boolean isNoPrefix() {
        return noPrefix;
    }

    public Class getPropertyClass() {
        return propertyClass;
    }

    public List> getTypeArguments() {
        return Collections.unmodifiableList(typeArguments);
    }

    public Optional getAnnotatedElement() {
        return Optional.ofNullable(annotatedElement);
    }

    private String parseDefaultValue(String defaultValue) {
        if (defaultValue.equals(ConfigProperty.UNDEFINED_DEFAULT)) {
            return null;
        }
        return defaultValue;
    }

    private static Class classOf(Parameter parameter) {
        return parameter.getType();
    }

    private static List> typeArgsOf(Parameter parameter) {
        Optional>> typeArgs = Optional
                .ofNullable(parameter.getParameterizedType())
                .filter(type -> type instanceof ParameterizedType)
                .map(type -> (ParameterizedType) type)
                .map(type -> Stream.of(type.getActualTypeArguments())
                        .map(argument -> (Class) argument)
                        .collect(Collectors.toList())
                );

        return typeArgs.orElseGet(Collections::emptyList);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy