Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update README with examples #30

Merged
merged 4 commits into from
Jan 20, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 102 additions & 7 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -24,30 +24,125 @@ CNF-01 is a library that provides immutable configuration for Java projects. Imm
// add instructions how people can start to use your project
=== Configuration

All sources of configuration can be used with the `Configuration` interface. It provides the method `asMap()` which returns the immutable configurations.
All the sources are usable with the same `Configuration` -interface. It has a single function:

An example with `PathConfiguration`:
[,java]
----
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:

[,java]
----
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`:

[,java]
----
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:

[,bash]
----
bar=foo
foo=bar
----

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

[,java]
----
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`:

[,java]
----
Configuration configuration = new PathConfiguration("file/path");
Map<String, String> configurationMap = configuration.asMap();
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`:

[,java]
----
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`:

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

=== Default configuration

You might want to specify default configurations in case something brakes. For example, the file path in the code block above might not be found. In the following example, notice how the Map with default configurations are given through the `ImmutabilitySupportedMap` object to ensure type safety. `DefaultConfiguration` only takes an `ImmutableMap` (provided in CNF-01) as a parameter for the defaults.
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`:

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

DefaultConfiguration defaultConfiguration = new DefaultConfiguration(
new PathConfiguration("file/path"),
defaults
new PathConfiguration("invalid.path"), // uses PathConfiguration that will throw an exception
defaults
);
Map<String, String> configurationMap = defaultConfiguration.asMap();

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

=== Configuration objects in your project
Expand Down