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

fi.jubic.easyconfig.internal.initializers.RootInitializerParser Maven / Gradle / Ivy

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

import fi.jubic.easyconfig.extensions.ConfigExtension;
import fi.jubic.easyconfig.extensions.ConfigExtensionProvider;
import fi.jubic.easyconfig.internal.ConfigPropertyDef;
import fi.jubic.easyconfig.internal.MappingContext;
import fi.jubic.easyconfig.internal.Result;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class RootInitializerParser implements InitializerParser {
    private static final List PARSERS = Arrays.asList(
            new ParameterizedConstructorInitializerParser(),
            new SetterInitializerParser(),
            new BuilderClassInitializerParser()
    );

    @Override
    public  Optional>> parse(
            MappingContext context,
            ConfigPropertyDef propertyDef
    ) {
        return PARSERS.stream()
                .map(parser -> parser.parse(context, propertyDef))
                .filter(Optional::isPresent)
                .map(Optional::get)
                .findFirst()
                .map(result -> result.flatMap(
                        initializer -> wrapExtensions(propertyDef, initializer)
                ));
    }

    private  Result> wrapExtensions(
            ConfigPropertyDef propertyDef,
            Initializer initializer
    ) {
        Optional optionalElement = propertyDef.getAnnotatedElement();
        if (!optionalElement.isPresent()) {
            return Result.of(initializer);
        }

        List extensionAnnotations = Stream
                .of(optionalElement.get().getAnnotations())
                .filter(annotation -> Objects.nonNull(
                        annotation.annotationType()
                                .getAnnotation(ConfigExtension.class)
                ))
                .collect(Collectors.toList());

        if (extensionAnnotations.isEmpty()) {
            return Result.of(initializer);
        }

        Initializer wrappedInitializer = initializer;

        for (Annotation annotation : extensionAnnotations) {
            ConfigPropertyDef providerDef = ConfigPropertyDef.buildForExtensionProvider(
                    annotation
            );

            MappingContext context = new MappingContext(propertyDef.getPropertyClass());

            final Initializer finalWrappedInitializer = wrappedInitializer;

            Result> wrappedInitializerResult = PARSERS.stream()
                    .map(parser -> parser.>parse(
                            context,
                            providerDef
                    ))
                    .filter(Optional::isPresent)
                    .map(Optional::get)
                    .findFirst()
                    .orElseGet(() -> Result.message(
                            context.format("No suitable initializer found")
                    ))
                    .map(providerInitializer -> (prefix, envProvider) -> finalWrappedInitializer
                            .initialize(prefix, envProvider)
                            .flatMap(wrappedInstance -> providerInitializer
                                    .initialize(prefix, envProvider)
                                    .map(provider -> provider.extend(annotation, wrappedInstance))
                            )
                    );

            if (wrappedInitializerResult.hasMessages()) {
                return wrappedInitializerResult;
            }
            wrappedInitializer = wrappedInitializerResult.getValue();
        }
        return Result.of(wrappedInitializer);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy