-
Notifications
You must be signed in to change notification settings - Fork 0
Annotations
EveryConfig's binding annotations live in br.com.finalcraft.everyconfig.annotation. They layer on top of
plain Jackson, so native @Json* annotations keep working too (see Entity Binding).
Renames a field's key and/or applies a case transform. Resolution order: @Key → @JsonProperty → field name.
@Key(transformCase = KeyTransformCase.KEBAB_CASE)
public int maxPoolSize; // -> "max-pool-size"
@Key("custom-host")
public String host; // -> "custom-host"
@Key(transformCase = KeyTransformCase.SNAKE_CASE)
public int ttlSeconds; // -> "ttl_seconds"KeyTransformCase: NONE, KEBAB_CASE, SNAKE_CASE, CAMEL_CASE, UPPER_CAMEL_CASE.
Apply one case to every property of a class instead of annotating each field. Use Jackson's @JsonNaming
with the ready-made KeyCaseStrategy.Kebab / KeyCaseStrategy.Snake (in
br.com.finalcraft.everyconfig.binding.introspect):
@JsonNaming(KeyCaseStrategy.Kebab.class)
class PoolConfig {
public int maxPoolSize = 10; // -> "max-pool-size"
public String serverHost = "h"; // -> "server-host"
@Key("HOST") // a field-level @Key overrides the strategy
public String legacy = "x"; // -> "HOST" (verbatim)
}It is opt-in per class (not installed globally), so only annotated classes are affected. A field-level @Key
always wins — @Key("literal") keeps its name verbatim and @Key(transformCase = ...) applies its own case.
On a field it seeds a block comment; on a type it seeds the file header. String[] value = multi-line.
@Comment({"First line", "second line"}) // OVERRIDE (default): re-seeded every save
public int timeout = 30;
@Comment(value = "tune me", mode = CommentMode.SET_IF_ABSENT) // written only if absent
public int retries = 3;-
CommentMode.OVERRIDE(default) — a doc fix in code propagates to existing files. -
CommentMode.SET_IF_ABSENT— a user-edited comment wins. - A class-level
@Commentbecomes the file header (useSET_IF_ABSENTto preserve a user's header). - On a
NONE-fidelity codec the seed is a no-op (no comment emitted). See Default Values & Comments.
@Section("database.pool")
@Key(transformCase = KeyTransformCase.KEBAB_CASE)
public int maxSize = 50; // written at database.pool.max-size, surfaced back on readA flat field is relocated to the nested path on write and brought back on read. The path is relative to the
field's owner, so a @Section field of a nested POJO is relocated under that POJO's own location too.
class Server {
@Section("network.tuning")
public int backlog = 128; // a Server at "server" -> server.network.tuning.backlog
}Not inside a
List/Mapelement. A@Sectionon a field of a collection element is unsupported — a collection element has no stable path. A sectioned type honorsObsoletePolicy.REMOVE(it is no longer forced toPRESERVE).
Marks the field whose value becomes the section key when a collection of the type is stored via setValue
and read via getList (the keyed layout is automatic — there are no dedicated methods).
class Account {
@KeyIndex public String name;
public int balance;
}Exactly one @KeyIndex per class; valid types are String, the boxed/primitive numerics, boolean, and
UUID. See @KeyIndex Collections.
A method (no args, or a single ConfigContext) invoked once around a bind. @PostLoad is the most common —
use it to validate or derive state after the tree is read into the entity. The ConfigContext carries the
bound section() and, only at @PostLoad, the lenient-bind issues().
class Cfg {
public int port = 25565;
@PostLoad
void validate() {
if (port < 1 || port > 65535) throw new IllegalStateException("bad port");
}
@PostLoad
void check(ConfigContext ctx) { // ctx.issues() are the lenient-bind issues (PostLoad only)
if (!ctx.issues().isEmpty()) log.warn("config had {} issues", ctx.issues().size());
}
}- The four hooks fire around the POJO ⇄ tree binding (
read/write), not the file flush. - Inherited hook methods (super + sub) all run, de-duplicated by method name.
- An exception thrown inside is wrapped in a
BindException(aBindExceptionthrown inside propagates as-is). - The opt-in
ConfigLifecycleinterface offers the same four hooks for types you cannot annotate.
→ See also Entity Binding · @KeyIndex Collections
EveryConfig · br.com.finalcraft:EveryConfig · One config API, every format, comments included · made by Petrus Pradella
Getting Started
Core Concepts
Typed Binding
Operations
Reference
Contributing