package org.wildfly.swarm.container.config; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.stream.Stream; import javax.enterprise.inject.Vetoed; import org.wildfly.swarm.spi.api.config.Builder; import org.wildfly.swarm.spi.api.config.ConfigKey; import org.wildfly.swarm.spi.api.config.ConfigView; import org.wildfly.swarm.spi.api.config.Resolver; import org.wildfly.swarm.spi.api.config.SimpleKey; /** * A view of merged/activated configurations. * * <p>If an explicit properties object is provided ({@link #withProperties(Properties)}, then * the System properties will be completely ignored. If not, then System properties will be * inspected, and any non-property based configuration will be reflect <b>back</b> into the * live and active System properties.</p> * * @author Bob McWhirter */ @Vetoed public class ConfigViewImpl implements ConfigView { /** * Construct a new view. */ public ConfigViewImpl() { this.strategy = new ConfigResolutionStrategy(); } /** * Supply explicit properties object for introspection and outrespection. * * @param properties The properties. * @return This view. */ public ConfigViewImpl withProperties(Properties properties) { if (properties != null) { this.properties = properties; this.strategy.withProperties(properties); } return this; } public ConfigViewImpl withProperty(String name, String value) { this.strategy.withProperty(name, value); return this; } public ConfigViewImpl withEnvironment(Map<String, String> environment) { if (environment != null) { this.strategy.withEnvironment(environment); } else { this.strategy.withEnvironment(System.getenv()); } return this; } /** * Define the tail-end, default {@code ConfigNode}. * * @param defaultConfig The defaults. * @return This view. */ public ConfigViewImpl withDefaults(ConfigNode defaultConfig) { this.strategy.defaults(defaultConfig); return this; } /** * Register a named {@code ConfigNode}. * * @param name The name to register. * @param config THe node to register. */ public synchronized void register(String name, ConfigNode config) { List<ConfigNode> nodes = this.registry.get(name); if (nodes == null) { nodes = new ArrayList<>(); this.registry.put(name, nodes); } nodes.add(config); } /** * Return the list of all registered node names. * * @return The list of registered node names. */ public Set<String> registered() { return this.registry.keySet(); } /** * Retrieve a configuration value by key. * * @param key The possibly complex key. * @return The value if present, otherwise {@code null}. */ public Object valueOf(ConfigKey key) { return this.strategy.valueOf(key); } void withProfile(String... names) { for (String name : names) { List<ConfigNode> nodes = this.registry.get(name); if (nodes != null) { nodes.forEach(node -> { this.strategy.add(node); }); } } } void withProfile(List<String> names) { withProfile(names.toArray(new String[]{})); } public void activate() { this.strategy.activate(); } // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ @Override public Properties asProperties() { return this.strategy.asProperties(); } @Override public Set<SimpleKey> simpleSubkeys(ConfigKey prefix) { return this.strategy.simpleSubkeysOf(prefix); } @Override public boolean hasKeyOrSubkeys(ConfigKey subPrefix) { return this.strategy.hasKeyOrSubkeys(subPrefix); } public Resolver<String> resolve(ConfigKey key) { return new Builder<>(this, key).as(String.class); } public Stream<ConfigKey> allKeysRecursively() { return this.strategy.allKeysRecursively(); } private Properties properties; private Map<String, List<ConfigNode>> registry = new HashMap<>(); private ConfigResolutionStrategy strategy; }