Annotations
Coat provides three annotations, a type-level annotation @Coat.Config
and
two method-level annotations @Coat.Param
and @Coat.Embedded
.
The type-level annotation is mandatory. It is the indicator for the annotation processor which interfaces need to be proceessed.
@Coat.Param
and @Coat.Embedded
are mutually exclusive.
@Coat.Config
Each interface that should be processed by the annotation processor must be
annotated with @Coat.Config
.
The generated builder class will always be generated in the same package as the annotated interface.
The name of the generated builder class is by default the interface name with
Builder
appended to it.
@Coat.Config
(Javadoc) supports the following attributes:
className
The className
can be specified to generate a builder class with a different
name than when applying the above mentioned naming rules. When className
is
specified it will be used as the generated builder class name. It will still be
generated in the same package as the annotated interface.
1@Coat.Config(className = "MyConfigBuilder")
2public interface AppConfig {
3 …
4}
casing
By default (if not explicitly specified by @Coat.Param#key) Coat expects the key in the config file exactly as the accessor methods name (respecting upper/lower case). To allow for different formats of keys without having to explicitly declare each key, Coat provides a CasingStrategy
.
AS_IS
- The default. The key is expected in the same case as the accessor methods name.
SNAKE_CASE
- The typical snakeCase of Java method names is converted to snake_case. For example the method name “listenPort” would then be specified as “listen_port” in the config file.
KEBAB_CASE
- Similar to SNAKE_CASE, but instead of underscores an hyphen is used. “listenPort” would be expected as “listen-port”.
All the above strategies expect the accessor method names in camelCase (conforming to the Java code formatting conventions). Deviating from that conventions may lead to unexpected results.
1@Coat.Confg(casing = SNAKE_CASE)
2public interface AppConfig {
3 …
4}
stripGetPrefix
Coat is agnostic to the naming conventions of the accessor methods. Using the Java Bean Convention of prefixing the methods with “get” leads to strange config keys (that also include the “get” prefix). Therefore Coat strips these prefixes before inferring the key. So the accessor method “getListenPort” would be specified as “listenPort” in the config file, This is necessary when using Java Bean Validation as that specification requires the “get” prefix on all accessors that are about to be validated.
If the “get” prefix should not be stripped for some reason, the stripGetPrefix
can be set to false to prohibit that behavior.
1@Coat.Confg(stripGetPrefix = false)
2public interface AppConfig {
3 public boolean getMeABeer();
4 …
5}
converters
Coat supports registering custom converters via a static method on the Coat
class.
Converters can also be registered declaratively with the converters
attribute. It expects an array of Converter classes to register.
1@Coat.Confg(converters = {
2 UuidConverter.class,
3 CurrencyConverter.class,
4})
5public interface AppConfig {
6 public UUID uuid();
7 public Currency currency();
8 …
9}
listParser
Since version 0.0.4 Coat supports Arrays and other collection types. By default it splits the values given in the config file on whitespace. To define a different format to use for Arrays and collections a custom ListParser can be registered.
Since version 1.0.0 Coat provides such an optional ListParser for splitting config values on commas, ignoring any whitespace around the commas. Of course, other custom ListParsers can be implemented and specified in the same way.
1@Coat.Confg(listParser = CommaSeparatedListParser.class)
2public interface AppConfig {
3 public InetAddress[] remoteAdresses();
4 …
5}
@Coat.Param
Since version 0.0.4 the @Coat.Param
annotation on accessor methods is optional.
@Coat.Param
(Javadoc) supports the following attributes:
key
The parameter key
specifies the name of the key
as it must be specified in the config file (or the Properties
or Map
object with which the config class is instantiated).
If this key
is not specified, it will be automatically inferred from the accessor methods name, respecting the casing and stripGetPrefix parameters of the corresponding @Coat.Config
annotation. By default the key
will be exactly the same as the accessor methods name.
1@Coat.Param(key = "listen-port")
2public int port();
defaultValue
A parameter defaultValue
can be specified to define a default
value that will be used if the config key is missing in the config file.
The default value must be specified as a String in the same form it would
be specified in the config file. For example:
1@Coat.Param(defaultValue = "8080")
2public int port();
The generated config would return the value that was specified in the
config file or 8080
if no port was specified.
converter
Additionally to the corresponding parameter on the @CoatConfig
annotation a converter can be specified on the accessor method itself. This will override the default converter specified on the interface.
1@Coat.Param(converter = MyDateConverter.class)
2public LocalDate startTime();
Use this attribute sparingly and prefer the corresponding attribute on the interface-level annotation @Coat.Config
as different formats for the same data types in the same config can be very surprising.
listParser
Additionally to the corresponding parameter on the @CoatConfig
annotation a ListParser can be specified on the accessor method itself. This will override the default ListParser specified on the interface.
1@Coat.Param(listParser = MyListParser.class)
2public String[] preferredRoles();
Use this attribute sparingly and prefer the corresponding attribute on the interface-level annotation @Coat.Config
as different formats for specifying lists in the same config can be very surprising.
@Coat.Embedded
When using nested configurations the
annotation @Coat.Embedded
must be used instead of @Coat.Param
on the
corresponding accessor method.
When using @Coat.Embedded
the return type of the accessor method must
be a @Coat.Config
annotated interface.
@Coat.Embedded
(Javadoc) supports the following attributes:
key
The parameter key
specifies the prefix for the config parameters of the
embedded config. See @Coat.Param#key for
more details about this attribute.
1@Coat.Embedded(key = "broker")
2public MqttConfig mqtt();
keySeparator
The parameter keySeparator
can be specified to define the
separator between the prefix and the actual config key of the embedded
config. It defaults to a single dot.
1@Coat.Embedded(keySeparator = "-")
2public MqttConfig mqtt();