-
Notifications
You must be signed in to change notification settings - Fork 0
API Cheat Sheet
A one-page reference. See the linked pages for detail.
Open / lifecycle — Lifecycle, Reload & Watching
Config cfg = Config.open(path, codec); // ABSENT / EMPTY / PARSE_FAILED_BACKED_UP / OK
Config cfg = Config.open("settings.yml"); // codec from the extension (String|File|Path)
Config cfg = Config.open(path, codec, BackStore.Durability.FSYNC); // OS_CACHE (default) | FSYNC
cfg.save(); cfg.saveIfDirty(); cfg.saveAsync();
cfg.reload(); // OK / ABSENT / PARSE_FAILED_KEPT
cfg.onReload(runnable).withAutoReload(Duration.ofSeconds(2)); cfg.stopAutoReload();
cfg.withAutoReload(Duration.ofSeconds(2), true); // also hash content (catch same-size edits)
cfg.close(); // AutoCloseable
cfg.lastLoadStatus(); cfg.isDivergedFromDisk(); cfg.getLastModified(); cfg.hasBeenModified();
open(String|File|Path)derives the codec from the file-name extension and throwsCodecExceptionon a missing/unknown one — it never guesses. Pass a codec to override.
Config mem = Config.inMemory(); // full typed/POJO API, no file; save() throws
Config raw = new Config(); // no codec at all — native values only (scalar/Map/list/JsonNode)
Config cfg = Config.open("server.yml");
cfg.save(new JsonCodec()); // one-shot persist as JSON; live codec stays YAML
cfg.changeCodec(new TomlCodec()); // switch the format for every subsequent save()
inMemory()bindsInMemoryCodec, sosetValue(path, pojo),mergeValue(path, pojo),getValue(path, type)and the annotations all work — but there is no text format, sosave()throws.save(Codec)writes the tree once in another format to the same file without touching the file name (a later extension-inferredopenwould pick the name's codec, not the one you saved with).
Set / remove — The Dynamic API
cfg.setValue(path, value); // null value deletes; auto-vivifies objects
cfg.setValue(path, value, comment);
cfg.removeValue(path); // booleangetString getInt getLong getDouble getBoolean getStringList getList getUUID // + (path, default) forms
getValue(path) // unwrapped scalar / node
getNode(path) // raw JsonNode or null
getStringon an object node returns the default (never the raw JSON); on an array it joins the elements with newlines.getUUID(path)andgetUUID(path, def)are both tolerant — a malformed or absent value yieldsnull/the default, never throws (like the numeric getters).
cfg.contains(path);
cfg.getKeys(); cfg.getKeys(path); cfg.getKeys(path, true /*deep*/);
cfg.getConfigSection(path); // always a view; use cfg.contains(path) for existence
cfg.getRoot(); // live ObjectNode escape hatchThe path separator is fixed at
.. A key that itself contains a dot is escaped with a backslash, sorates.usd\.brladdresses the single key"usd.brl"underrates;\\is a literal backslash. The escape is a no-op for ordinary keys.cfg.getDouble("rates.usd\\.brl"); // reads the key "usd.brl" under "rates" (Java string: \\ → \)
Defaults & comments — Default Values & Comments
cfg.getOrSetValueIfAbsent(path, def);
cfg.getOrSetValueIfAbsent(path, def, comment); // seeds comment if absent
cfg.getOrMergeValue(path, def); // field-level get-or-seed: each missing field of def is added, the file wins for fields it has
cfg.getOrMergeValue(path, def, target); // ... reading the result into target
cfg.setComment(path, text); // authoritative (CommentType.BLOCK default)
cfg.setDefaultComment(path, text); // set-if-absent
cfg.getComment(path); cfg.getComment(path, CommentType.SIDE);
cfg.setHeader("line1", "line2"); cfg.setDefaultHeader(...); cfg.getHeader(); cfg.clearHeader(); // file header
cfg.setFooter(...); cfg.setDefaultFooter(...); cfg.getFooter(); cfg.clearFooter(); // file footer
cfg.setValueIfAbsent(path, value); cfg.setValueIfAbsent(path, value, comment); // void seed
MigrationResult r = cfg.migrateKey(oldPath, newPath); // moves data + the key's whole comment subtree
// r: MOVED | SAME_PATH | INVALID_ROOT | ALREADY_MIGRATED | SOURCE_ABSENT (r.moved() for the only mutating case)
migrateKeyis safe to run unconditionally on every startup: the returnedMigrationResulttells a real move (MOVED) from a benign re-run (ALREADY_MIGRATED, source already moved) and from a likely typo (SOURCE_ABSENT, neither side exists). When both paths exist the source overwrites the target (MOVED).
Binding — Entity Binding
T pojo = cfg.loadAs(Type.class, codec); // bind whole tree + @PostLoad
T sub = cfg.getValue("a.b", Type.class); // bind a subtree (codec from open())
T sub = cfg.getValue("a.b", Type.class, codec); // ... or an explicit codec
EntityBinder<T> b = cfg.bind(Type.class[, codec][, opts]); // b.read(""); b.write("", pojo); b.lastLoadIssues();
cfg.setValue(path, pojo); // a POJO setValue REPLACES the subtree at the path
cfg.mergeValue(path, pojo); // merge instead — unknown keys under the path survive
cfg.mergeValue(path, pojo, comment); // ... and seed the path's comment if absent
BindResult<T> r = cfg.loadAsResult(Type.class, codec); // also: b.readResult("")
r.value(); r.issues(); r.hasIssues(); // issues travel with the value
BindOptions.defaults()
.withCoercion(BindOptions.Coercion.STRICT) // or LENIENT (default)
.withObsoletePolicy(BindOptions.ObsoletePolicy.COMMENT_OUT); // PRESERVE (default) | REMOVE | COMMENT_OUT
getValue's 2-arg form needs a codec fromopen()(elseIllegalStateException); an absent path binds the type's defaults, a root path (""/null) binds the whole tree.COMMENT_OUTkeeps the obsolete key but stamps a deprecation block comment — LOSSLESS codecs only (degrades toPRESERVEon a NONE/LOSSY codec).
@KeyIndex collections — @KeyIndex Collections
cfg.setValue(path, collection); // auto key-major when the element type has @KeyIndex
List<T> back = cfg.getList(path, Type.class); // detects the indexed section by node shape
BindResult<List<T>> r = cfg.getListResult(path, Type.class); // the list + read issuesAnnotations — Annotations
@Key(value, transformCase) @Comment(value, mode) @Section("a.b") @KeyIndex @PostLoad
KeyTransformCase.{NONE, KEBAB_CASE, SNAKE_CASE, CAMEL_CASE, UPPER_CAMEL_CASE}
CommentMode.{OVERRIDE, SET_IF_ABSENT}
@JsonNaming(KeyCaseStrategy.Kebab.class) // class-wide case (or .Snake); a field @Key overrides it
@JsonNaming(KeyCaseStrategy.Snake.class)
Codecs — Codecs & Formats
new YamlCodec() // LOSSLESS yml, yaml
new JsonCodec() // NONE json
new TomlCodec() // LOSSLESS toml (no null)
new JsoncCodec() // LOSSY jsonc
CodecRegistry.defaults().forFile("a.toml"); // resolve by extensionEveryConfig · br.com.finalcraft:EveryConfig · One config API, every format, comments included · made by Petrus Pradella
Getting Started
Core Concepts
Typed Binding
Operations
Reference
Contributing