Environment.java
package io.github.jonloucks.variants.api;
import java.util.*;
import static io.github.jonloucks.contracts.api.Checks.nullCheck;
import static java.util.Collections.emptyList;
import static java.util.Optional.ofNullable;
/**
* Responsibility: Locating variances from multiple sources.
* <p>
* A breadth first search into each source looking for provided value for a specific Variant
* Each key in the Variant is search in order of insertion.
* Fallback values (defaults) are only used if no values are found in any of the sources.
* </p>
*/
public interface Environment {
/**
* Find a variance if it exists.
*
* @param variant the Variant
* @return the optional value
* @param <T> the type of variance value
*/
<T> Optional<T> findVariance(Variant<T> variant);
/**
* Get required variance or throw an exception.
*
* @param variant the Variant
* @return the variance
* @throws VariantException if not found
* @param <T> the type of variance value
*/
default <T> T getVariance(Variant<T> variant) {
return findVariance(variant).orElseThrow(() -> new VariantException("Variant not found. " + variant + "."));
}
/**
* Responsibility: Configuration for creating a new Environment
*/
interface Config {
/**
* @return the list of sources. An empty list is allowed.
*/
default List<VariantSource> getSources() {
return emptyList();
}
/**
* Responsibility: Builder a configuration used to create a new Environment
*/
interface Builder extends Environment.Config {
/**
* Add a new source
*
* @param source the source to add
* @return this builder
*/
Builder addSource(VariantSource source);
/**
* Add a new source based on a java.util.Map.
*
* @param map the Map
* @return this builder
*/
default Builder addMapSource(Map<String, ?> map) {
final Map<String, ?> validMap = nullCheck(map, "Map must be present.");
return addSource(k -> Optional.ofNullable(validMap.get(k)).map(Object::toString));
}
/**
* Add a new source based on a java.util.Properties.
*
* @param properties the Properties
* @return this builder
*/
default Builder addPropertiesSource(Properties properties) {
final Properties validProperties = nullCheck(properties, "Properties must be present.");
return addSource(k -> ofNullable(validProperties.getProperty(k)));
}
/**
* Add System.getProperty as a source.
*
* @return this builder
*/
default Builder addSystemPropertiesSource() {
addSource(k -> ofNullable(System.getProperty(k)));
return this;
}
/**
* Add System.getenv as a source.
*
* @return this builder
*/
default Builder addSystemEnvironmentSource() {
addSource(k -> ofNullable(System.getenv(k)));
return this;
}
}
}
}