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

com.ocadotechnology.config.ConfigFactory Maven / Gradle / Ivy

There is a newer version: 16.6.21
Show newest version
/*
 * Copyright © 2017-2023 Ocado (Ocava)
 *
 * 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 com.ocadotechnology.config;

import java.util.Arrays;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.ocadotechnology.config.ConfigManager.PrefixedProperty;

final class ConfigFactory {

    private ConfigFactory() {
        throw new UnsupportedOperationException("Static utility class that shouldn't be instantiated");
    }

    static > Config read(Class e, PropertiesAccessor props, ImmutableSet prefixedProperties) {
        return readInternal(e, props, e.getSimpleName(), prefixedProperties);
    }

    @SuppressWarnings("unchecked rawtypes") //It is actually checked (subEnum.isEnum()) and the types are only raw because Enum>
    private static > Config readInternal(Class cls, PropertiesAccessor props, String qualifier, ImmutableSet prefixedProperties) {
        Builder builder = new Builder<>(cls, qualifier);
        for (E constant : cls.getEnumConstants()) {
            String val = props.getProperty(qualifier + "." + constant.name());
            if (val != null) {
                builder.put(constant, new ConfigValue(val, ImmutableMap.of()));
            }
        }
        for (Class subEnum : cls.getDeclaredClasses()) {
            String subQualifier = qualifier + "." + subEnum.getSimpleName();
            Preconditions.checkState(subEnum.isEnum());
            builder.addSubConfig(readInternal((Class)subEnum, props, subQualifier, prefixedProperties));
        }

        builder.managePrefixedProperties(cls, qualifier, prefixedProperties);

        return builder.build();
    }

    private static class Builder> {
        private final Class cls;
        private final EnumMap configValues;
        private final Map> subConfig;
        private final String qualifier;

        public Builder(Class cls, String qualifier) {
            this.cls = cls;
            this.qualifier = qualifier;
            configValues = new EnumMap<>(cls);
            subConfig = new HashMap<>();
        }

        private Builder put(E key, ConfigValue val) {
            configValues.put(key, val);
            return this;
        }

        private void addSubConfig(Config config) {
            subConfig.put(config.cls, config);
        }

        private void managePrefixedProperties(
                Class cls,
                String qualifier,
                ImmutableSet prefixedProperties) {

            for (PrefixedProperty prefixedProperty : prefixedProperties) {
                if (!qualifier.equals(prefixedProperty.qualifier)) {
                    continue;
                }

                Optional enumConfigItem = Arrays.stream(cls.getEnumConstants())
                        .filter(configItem -> configItem.name().equals(prefixedProperty.constant))
                        .findFirst();

                enumConfigItem.ifPresent(e -> updatePrefixes(prefixedProperty, e));
            }
        }

        private void updatePrefixes(PrefixedProperty prefixedProperty, E enumConfigItem) {
            ImmutableMap.Builder, String> prefixedValues = ImmutableMap.builder();

            ConfigValue configValue = configValues.get(enumConfigItem);

            prefixedValues.put(prefixedProperty.prefixes, prefixedProperty.propertyValue);

            String currentDefaultValue = null;

            if (configValue != null) {
                prefixedValues.putAll(configValue.prefixedValues);
                currentDefaultValue = configValue.currentValue;
            }

            configValues.put(enumConfigItem, new ConfigValue(currentDefaultValue, prefixedValues.build()));
        }

        private Config build() {
            return new Config<>(cls, Maps.immutableEnumMap(configValues), ImmutableMap.copyOf(subConfig), qualifier);
        }

    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy