Skip to content

Technical documentation

ljacqu edited this page Feb 2, 2020 · 2 revisions

This is an extended technical description of the ConfigMe classes. Please refer to the Short technical overview for a high-level introduction.

As we saw in the technical overview, typically you provide three things to create a settings manager with the SettingsManagerBuilder:

  • File object to the configuration file that should be read and written to
  • MigrationService to update older configurations to the newest state
  • SettingsHolder classes which define all the properties of your configuration

Alternatively, you can provide your own PropertyResource (instead of a File) and/or your own ConfigurationData (instead of SettingsHolder classes).

Architecture overview

We now discuss the classes in ConfigMe and their responsibilities.

PropertyResource

The property resource allows to read and write to a medium, typically a file. It has two methods to do exactly that:

  • PropertyReader createReader() – creates a reader to get the values from
  • void exportProperties(ConfigurationData) – writes the state of ConfigurationData to the resource

The out of the box implementation of PropertyResource is YamlFileResource, which reads and writes YAML to a file. PropertyResource and PropertyReader are responsible for dealing with the format (e.g. YAML) and the medium (e.g. file) and do not keep any state about the properties of the configuration.

PropertyReader: reading from the resource

You can create a PropertyReader with a method on PropertyResource; this is an object that returns the values as read from the file. The reader delivers a read-only snapshot view of the file at the time the method was called on the PropertyResource, i.e. newer changes to the file will not be reflected in the reader.

Writing to the resource

As seen above, PropertyResource also has a method to write the configuration data to the resource, namely exportProperties(ConfigurationData), writing all the data from the given ConfigurationData (property values & comments, discussed below).

Property classes

The interface Property (and its implementors) is a single property definition. It's defined by the following:

  • path at which the value is located in the property resource (the file)
  • default value if the property's value cannot be read from the property resource
  • its type, exhibited in the behavior of methods to convert to and from the property resource.

Property does not keep the value it is associated with. It does not keep any state whatsoever and solely serves as property definition, which could be reused in multiple setting managers.

All extensions of Property should extend the class BaseProperty, which guarantees null safety. This is a core concept of ConfigMe (see Introduction). A class hierarchy of existing Property implementations is available in Defining properties.

PropertyType

An extension of Property, TypeBasedProperty, takes a so-called PropertyType. Implement this interface for simple custom types, rather than extending BaseProperty itself. See also Custom property types.

SettingsHolder

The SettingsHolder interface is to be implemented by users to define their configuration. It contains Property instances as constants (public static final) on the classes, which ConfigMe will pick up on. As with Property, no state is kept in settings holder classes.

ConfigurationData

Contains all properties and comments as defined in the SettingsHolder classes. This class is stateful and keeps the value associated to the properties internally. This class is responsible for triggering the loading of the properties and allowing subsequent management of them (i.e. querying them and modifying them).

The ConfigurationData is built by the ConfigurationDataBuilder by default, but you could implement your own or provide your own ConfigurationData if you want. For instance, if you want to define properties differently, you could skip the SettingsHolder classes and create your own config, from which you build your own ConfigurationData.

SettingsManager

The settings manager unites property resource, configuration data and migration service (discussed later). It uses and delegates to those classes such that you only need to interact with the settings manager once you've created it.

MigrationService

The migration service is called by the settings manager and allows to rename properties or otherwise migrate an existing configuration to the newest state. If the migration service has changed something in the configuration, it can trigger a save to the resource so that the configuration is exported in a fully valid, up-to-date state.

Initialization of the configuration

Property lifecycle

When the SettingsManager is instantiated and the three main components—PropertyResource, ConfigurationData and MigrationService—are passed in, the configuration is loaded and it gets migrated.

A PropertyReader is created from the PropertyResource in order to be able to read from the file. This reader is passed to the ConfigurationData; it passes the property reader to all of the Property objects it consists of. Each property uses the reader to determine what value it has in the property resource, falling back to its default value in case there is no value or if it is invalid. The configuration data keeps the value for each property.

When the configuration data has saved the value for every property, the migration service is called. It is passed the ConfigurationData to check the current state of the configuration, as well as the property reader so that it can read other values from the resource (e.g. to check if there is a value at a property that has since been removed).

The migration service can change the values in the configuration data and signals back to the settings manager whether the configuration should be saved again, or not. If so, SettingsManager#save is called, which internally calls the PropertyResource and passes to it the ConfigurationData, instructing it to save all of the configuration data's values to the resource.

Quiz questions

  • Instead of a YAML file, you want to store your configuration values in a SQL database. What interfaces/classes do you need to provide a custom implementation for?

Navigation

« Custom property types Technical documentation Home