/**
* Copyright (c) 2013-2016, The SeedStack authors <http://seedstack.org>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.seedstack.seed.core.internal.configuration;
import org.seedstack.coffig.node.MapNode;
import org.seedstack.coffig.spi.ConfigurationComponent;
import org.seedstack.coffig.spi.ConfigurationProvider;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
public class PrioritizedProvider implements ConfigurationProvider {
private final List<PrioritizedConfigurationProvider> providers = new CopyOnWriteArrayList<>();
private final AtomicBoolean dirty = new AtomicBoolean(true);
@Override
public MapNode provide() {
MapNode mapNode = providers.stream()
.sorted(PrioritizedConfigurationProvider::compareTo)
.map(PrioritizedConfigurationProvider::getConfigurationProvider)
.map(ConfigurationProvider::provide)
.reduce((conf1, conf2) -> (MapNode) conf1.merge(conf2))
.orElse(new MapNode());
dirty.set(false);
return mapNode;
}
@Override
public boolean isDirty() {
return dirty.get() || providers.stream().map(PrioritizedConfigurationProvider::getConfigurationProvider).filter(ConfigurationComponent::isDirty).count() > 0;
}
@Override
public PrioritizedProvider fork() {
PrioritizedProvider fork = new PrioritizedProvider();
for (PrioritizedConfigurationProvider prioritizedConfigurationProvider : providers) {
fork.registerProvider((ConfigurationProvider) prioritizedConfigurationProvider.getConfigurationProvider().fork(), prioritizedConfigurationProvider.getPriority());
}
return fork;
}
public PrioritizedProvider registerProvider(ConfigurationProvider configurationProvider, int priority) {
providers.add(new PrioritizedConfigurationProvider(priority, configurationProvider));
dirty.set(true);
return this;
}
private static class PrioritizedConfigurationProvider implements Comparable<PrioritizedConfigurationProvider> {
private final int priority;
private final ConfigurationProvider configurationProvider;
private PrioritizedConfigurationProvider(int priority, ConfigurationProvider configurationProvider) {
this.priority = priority;
this.configurationProvider = configurationProvider;
}
@Override
public int compareTo(PrioritizedConfigurationProvider o) {
return Integer.compare(priority, o.priority);
}
int getPriority() {
return priority;
}
ConfigurationProvider getConfigurationProvider() {
return configurationProvider;
}
}
}