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

cz.jalasoft.util.configuration.LifeConfig Maven / Gradle / Ivy

The newest version!
package cz.jalasoft.util.configuration;

import cz.jalasoft.util.configuration.key.PropertyKeyExtractor;
import cz.jalasoft.util.configuration.provider.ConfigProvider;
import cz.jalasoft.util.configuration.provider.HoconConfigProvider;
import cz.jalasoft.util.configuration.provider.JavaPropertyConfigProvider;
import cz.jalasoft.util.configuration.source.ConfigSource;
import cz.jalasoft.util.converter.string.StringConverter;

import java.io.IOException;
import java.lang.reflect.Proxy;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import static cz.jalasoft.util.ArgumentAssertion.mustNotBeNull;
import static cz.jalasoft.util.ArgumentAssertion.mustNotBeNullOrEmpty;
import static cz.jalasoft.util.configuration.key.PropertyKeyExtractors.*;

/**
 * The main access point of a configuration. This class
 * provides methods for retreving external configuration.
 *
 * @author Honza Lastovicka
 */
public final class LifeConfig {

    private static final String DEFAULT_CONFIG_FILE_NAME = "configuration.conf";

    public static  T load(Class type) {
        mustNotBeNull(type, "Configuration type");

        return pretending(type)
                .load();
    }

    public static  LifeConfig pretending(Class type) {
        mustNotBeNull(type, "Configruation type");

        return new LifeConfig(type)
                .fromClasspath(DEFAULT_CONFIG_FILE_NAME)
                .javaProperties();
    }

    //-------------------------------------------------------------------------------------
    //INSTANCE SCOPE
    //-------------------------------------------------------------------------------------


    final Class type;
    final ConverterRegistry converterRegistry;
    ConfigSource source;
    ConfigProvider provider;
    final PropertyKeyExtractor keyExtractor;
    boolean isLife;


    private LifeConfig(Class type) {
        this.type = type;
        this.converterRegistry = ConverterRegistry.standardConverters();
        this.keyExtractor = prefixAnnotationAwareAnd(keyAnnotationValueOr(getterExtractingOr(methodName())));
    }

    /**
     * Registers custom converter from a string property to a data type.
     *
     * @param converter a converter from string, must not be null
     * @throws java.lang.IllegalArgumentException if type or converter is null
     */
    public  LifeConfig addConverter(StringConverter converter) {
        mustNotBeNull(converter, "Converter to be registered must not be null.");

        converterRegistry.addConverter(converter);
        return this;
    }

    public LifeConfig fromFile(String filePath) {
        mustNotBeNullOrEmpty(filePath, "Resource file path");

        Path file = Paths.get(filePath);
        return from(ConfigSource.file(file));
    }

    public LifeConfig fromFile(Path path) {
        mustNotBeNull(path, "Resource file");

        if (!Files.isRegularFile(path)) {
            throw new IllegalArgumentException("File path '" + path + "' must lead to a regular file.");
        }
        return from(ConfigSource.file(path));
    }

    public LifeConfig fromClasspath(String resourceName) {
        mustNotBeNullOrEmpty(resourceName, "Resource name");

        return from(ConfigSource.classpath(resourceName));
    }

    public LifeConfig from(ConfigSource source) {
        mustNotBeNull(source, "Config source");

        this.source = source;
        return this;
    }

    public LifeConfig format(ConfigProvider provider) {
        mustNotBeNull(provider, "Config provider");

        this.provider = provider;
        return this;
    }

    public LifeConfig life() {
        this.isLife = true;
        return this;
    }

    public LifeConfig javaProperties() {
        return format(new JavaPropertyConfigProvider());
    }

    public LifeConfig hocon() {
        return format(new HoconConfigProvider());
    }

    /**
     * Gets a dynamic implementation of an inserted annotated interface
     * as a provider of a configuration.
     *
     * @return never null
     */
    public T load() {
        new ConfigutrationInterfaceValidator(converterRegistry).validate(type);
        new ConverterAnnotationIntrospection(converterRegistry).introspect(type);
        new ConverterIntegrityValidator(converterRegistry).validate(type);

        reloadSourceIfNotLife();

        PropertyInvocationHandler handler = new PropertyInvocationHandler(this);
        return (T) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] {type}, handler);
    }

    private void reloadSourceIfNotLife() {
        if (!isLife) {
            try {
                provider.reload(source);
            } catch (IOException exc) {
                throw new RuntimeException("Cannot load properties from source " + source.name(), exc);
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy