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

com.ijson.config.base.AbstractConfigFactory Maven / Gradle / Ivy

package com.ijson.config.base;

import com.google.common.base.CharMatcher;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.ijson.config.api.IChangeListener;
import com.ijson.config.api.IChangeableConfig;
import com.ijson.config.api.IConfigFactory;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;

/**
 * @author cuiyongxu
 */
@SuppressWarnings({"ALL", "AlibabaAbstractMethodOrInterfaceMethodMustUseJavadoc"})
public abstract class AbstractConfigFactory implements IConfigFactory {
    private final ConcurrentMap m = Maps.newConcurrentMap();

    @Override
    public IChangeableConfig getConfig(String name) {
        IChangeableConfig config = m.get(name);
        if (config == null) {
            synchronized (this) {
                config = m.get(name);
                if (config == null) {
                    config = newConfig(name);
                    IChangeableConfig real = m.putIfAbsent(name, config);
                    if (real != null) {
                        config = real;
                    }
                }
            }
        }
        return config;
    }

    @Override
    public IChangeableConfig getConfig(String name, IChangeListener listener) {
        return getConfig(name, listener, true);
    }

    @Override
    public IChangeableConfig getConfig(String name, IChangeListener listener, boolean loadAfterRegister) {
        IChangeableConfig config = getConfig(name);
        config.addListener(listener, loadAfterRegister);
        return config;
    }

    @Override
    public boolean hasConfig(String name) {
        return m.containsKey(name);
    }

    private IChangeableConfig newConfig(String name) {
        CharMatcher matcher = CharMatcher.anyOf(",; |");
        if (matcher.matchesAnyOf(name)) {
            List names = Splitter.on(matcher).trimResults().omitEmptyStrings().splitToList(name);
            List list = Lists.newArrayList();
            list.addAll(names.stream().map(this::getConfig).collect(Collectors.toList()));
            return new MergedConfig(list);
        } else {
            return doCreate(name);
        }
    }

    protected abstract IChangeableConfig doCreate(String name);

    @Override
    public List getAllConfig() {
        return ImmutableList.copyOf(m.values());
    }


    private static class MergedConfig extends ChangeableConfig implements IChangeableConfig {
        private final List configs;

        MergedConfig(List configs) {
            super(Joiner.on(',').join(Collections2.transform(configs, IChangeableConfig::getName)));

            IChangeListener listener = config -> merge();

            // 注册单个配置文件的更新回调功能
            for (IChangeableConfig c : configs) {
                c.addListener(listener, false);
            }

            // 同名配置,排在前面的优先,所以按照做一次排序反转
            this.configs = Lists.newArrayList(configs);
            Collections.reverse(this.configs);

            // 首次merge配置
            merge();
        }

        private void merge() {
            Map m = Maps.newHashMap();
            for (IChangeableConfig c : this.configs) {
                m.putAll(c.getAll());
            }
            copyOf(m);
            notifyListeners();
        }

        @Override
        public String toString() {
            return "MergedConfig{" + "name=" + getName() + '}';
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy