Skip to content

teragrep/cnf_01

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Teragrep Configuration Library for Java

CNF-01 is a library that provides immutable configuration for Java projects. Immutability is achieved by converting the configuration source into an immutable Map. The resulting configuration Map can’t be altered even with modifying the underlying source.

Features

  • Provides immutable configurations for:

    1. configuration files / path properties (PathConfiguration)

    2. System Properties (PropertiesConfiguration)

    3. environment variables (EnvironmentConfiguration)

    4. command line arguments (ArgsConfiguration)

  • Default configurations in case the provided configurations from a source are not found or are otherwise broken (DefaultConfiguration)

How to use

Configuration

All the sources are usable with the same Configuration -interface. It has a single function:

Map<String, String> asMap() throws ConfigurationException;

System Properties

In Java, System properties can be utilized with System.setProperty(key, value).

System properties can be used as a configuration source in CNF-01 with the PropertiesConfiguration object. It has two constructors:

public PropertiesConfiguration(); // uses System.getProperties()
public PropertiesConfiguration(Properties properties); // uses any Java Properties given

Most likely the default constructor is what you’ll need, but in some cases the second constructor might become handy.

Here’s an example of using PropertiesConfiguration:

PropertiesConfiguration config = new PropertiesConfiguration(); // uses System.getProperties()
Map<String, String> result = config.asMap();

Configuration File

One of the supported configuration sources is a File. These are often marked with a ".properties" file extension but basically any Java’s File object will do. The properties have to be given in a key=value format in the File. For example:

bar=foo
foo=bar

A file can be used as a configuration source with the PathConfiguration object. It has two constructors:

public PathConfiguration(final String fileName); // Uses the filename
public PathConfiguration(final File file); // Uses Java's File object

Here’s an example of using PathConfiguration:

Configuration configuration = new PathConfiguration("file/path");
Map<String, String> configMap = new HashMap<>();
try {
    configMap = configuration.asMap();
} catch (ConfigurationException e) {
    // Handle the exception...
}

PathConfiguration throws an exception if the File is not found.

Read Default Configuration section to see how default configurations can be used to avert the need for the try-catch.

Command line arguments

Command line arguments (or any String[] args) can be utilized as a configuration source with the ArgsConfiguration object.

Here’s an example of using ArgsConfiguration:

public static void main(String[] args) {
    Configuration configuration = new ArgsConfiguration(args);
    Map<String, String> configMap = new HashMap<>();
    try {
        configMap = configuration.asMap();
    } catch (ConfigurationException e) {
        // Handle the exception...
    }
}

ArgsConfiguration throws an exception if the Strings in the array don’t follow the key=value format.

Read Default Configuration section to see how default configurations can be used to avert the need for the try-catch.

Environment Variables

EnvironmentConfiguration object supports Java’s System.getenv(), meaning the system’s environment variables. The constructor takes no arguments.

Here’s an example of using EnvironmentConfiguration:

Configuration configuration = new EnvironmentConfiguration();
Map<String, String> configMap = configuration.asMap();

Default configuration

Default configurations can be used in case the asMap() function throws ConfigurationException. If the function throws an exception, the defaults are used instead. Only PathConfiguration and ArgsConfiguration can currently throw an exception.

DefaultConfiguration follows the pattern of composable decorators introduced in Elegant Objects. Therefore, it takes another Configuration object as an argument in the constructor. The second argument is an ImmutableMap which is in the CNF-01 library as well.

Here’s an example of how to use DefaultConfiguration when paired with PathConfiguration:

Map<String, String> map = new HashMap<>();
map.put("foo", "bar");
ImmutableMap<String, String> defaults = new ImmutabilitySupportedMap<>(map).toImmutableMap();

DefaultConfiguration defaultConfiguration = new DefaultConfiguration(
    new PathConfiguration("invalid.path"), // uses PathConfiguration that will throw an exception
    defaults
);

Map<String, String> result = defaultConfiguration.asMap();

Configuration objects in your project

The configuration Map from CNF-01 shouldn’t be used directly in regular objects. It should only be passed to objects that are responsible for providing configured versions of other objects, in other words, Factories. The regular objects must not be configurable!

Small example with an Example object:

ExampleFactory exampleFactory = new ExampleFactory(configurationMap);
Example example = exampleFactory.example();

Here, the logic for instantiating an Example is in the ExampleFactory object, which receives the configuration map from CNF-01 as a parameter. This ensures that the main object Example is as clear as it can be.

Contributing

You can involve yourself with our project by opening an issue or submitting a pull request.

Contribution requirements:

  1. All changes must be accompanied by a new or changed test. If you think testing is not required in your pull request, include a sufficient explanation as why you think so.

  2. Security checks must pass

  3. Pull requests must align with the principles and values of extreme programming.

  4. Pull requests must follow the principles of Object Thinking and Elegant Objects (EO).

Read more in our Contributing Guideline.

Contributor License Agreement

Contributors must sign Teragrep Contributor License Agreement before a pull request is accepted to organization’s repositories.

You need to submit the CLA only once. After submitting the CLA you can contribute to all Teragrep’s repositories.