001/** 002 * Copyright (C) 2011-2012 Typesafe Inc. <http://typesafe.com> 003 */ 004package com.typesafe.config; 005 006import java.time.Duration; 007import java.util.List; 008import java.util.Map; 009import java.util.Set; 010import java.util.concurrent.TimeUnit; 011 012/** 013 * An immutable map from config paths to config values. Paths are dot-separated 014 * expressions such as <code>foo.bar.baz</code>. Values are as in JSON 015 * (booleans, strings, numbers, lists, or objects), represented by 016 * {@link ConfigValue} instances. Values accessed through the 017 * <code>Config</code> interface are never null. 018 * 019 * <p> 020 * {@code Config} is an immutable object and thus safe to use from multiple 021 * threads. There's never a need for "defensive copies." 022 * 023 * <p> 024 * Fundamental operations on a {@code Config} include getting configuration 025 * values, <em>resolving</em> substitutions with {@link Config#resolve()}, and 026 * merging configs using {@link Config#withFallback(ConfigMergeable)}. 027 * 028 * <p> 029 * All operations return a new immutable {@code Config} rather than modifying 030 * the original instance. 031 * 032 * <p> 033 * <strong>Examples</strong> 034 * 035 * <p> 036 * You can find an example app and library <a 037 * href="https://github.com/typesafehub/config/tree/master/examples">on 038 * GitHub</a>. Also be sure to read the <a 039 * href="package-summary.html#package_description">package overview</a> which 040 * describes the big picture as shown in those examples. 041 * 042 * <p> 043 * <strong>Paths, keys, and Config vs. ConfigObject</strong> 044 * 045 * <p> 046 * <code>Config</code> is a view onto a tree of {@link ConfigObject}; the 047 * corresponding object tree can be found through {@link Config#root()}. 048 * <code>ConfigObject</code> is a map from config <em>keys</em>, rather than 049 * paths, to config values. Think of <code>ConfigObject</code> as a JSON object 050 * and <code>Config</code> as a configuration API. 051 * 052 * <p> 053 * The API tries to consistently use the terms "key" and "path." A key is a key 054 * in a JSON object; it's just a string that's the key in a map. A "path" is a 055 * parseable expression with a syntax and it refers to a series of keys. Path 056 * expressions are described in the <a 057 * href="https://github.com/typesafehub/config/blob/master/HOCON.md">spec for 058 * Human-Optimized Config Object Notation</a>. In brief, a path is 059 * period-separated so "a.b.c" looks for key c in object b in object a in the 060 * root object. Sometimes double quotes are needed around special characters in 061 * path expressions. 062 * 063 * <p> 064 * The API for a {@code Config} is in terms of path expressions, while the API 065 * for a {@code ConfigObject} is in terms of keys. Conceptually, {@code Config} 066 * is a one-level map from <em>paths</em> to values, while a 067 * {@code ConfigObject} is a tree of nested maps from <em>keys</em> to values. 068 * 069 * <p> 070 * Use {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath} to convert 071 * between path expressions and individual path elements (keys). 072 * 073 * <p> 074 * Another difference between {@code Config} and {@code ConfigObject} is that 075 * conceptually, {@code ConfigValue}s with a {@link ConfigValue#valueType() 076 * valueType()} of {@link ConfigValueType#NULL NULL} exist in a 077 * {@code ConfigObject}, while a {@code Config} treats null values as if they 078 * were missing. (With the exception of two methods: {@link Config#hasPathOrNull} 079 * and {@link Config#getIsNull} let you detect <code>null</code> values.) 080 * 081 * <p> 082 * <strong>Getting configuration values</strong> 083 * 084 * <p> 085 * The "getters" on a {@code Config} all work in the same way. They never return 086 * null, nor do they return a {@code ConfigValue} with 087 * {@link ConfigValue#valueType() valueType()} of {@link ConfigValueType#NULL 088 * NULL}. Instead, they throw {@link ConfigException.Missing} if the value is 089 * completely absent or set to null. If the value is set to null, a subtype of 090 * {@code ConfigException.Missing} called {@link ConfigException.Null} will be 091 * thrown. {@link ConfigException.WrongType} will be thrown anytime you ask for 092 * a type and the value has an incompatible type. Reasonable type conversions 093 * are performed for you though. 094 * 095 * <p> 096 * <strong>Iteration</strong> 097 * 098 * <p> 099 * If you want to iterate over the contents of a {@code Config}, you can get its 100 * {@code ConfigObject} with {@link #root()}, and then iterate over the 101 * {@code ConfigObject} (which implements <code>java.util.Map</code>). Or, you 102 * can use {@link #entrySet()} which recurses the object tree for you and builds 103 * up a <code>Set</code> of all path-value pairs where the value is not null. 104 * 105 * <p> 106 * <strong>Resolving substitutions</strong> 107 * 108 * <p> 109 * <em>Substitutions</em> are the <code>${foo.bar}</code> syntax in config 110 * files, described in the <a href= 111 * "https://github.com/typesafehub/config/blob/master/HOCON.md#substitutions" 112 * >specification</a>. Resolving substitutions replaces these references with real 113 * values. 114 * 115 * <p> 116 * Before using a {@code Config} it's necessary to call {@link Config#resolve()} 117 * to handle substitutions (though {@link ConfigFactory#load()} and similar 118 * methods will do the resolve for you already). 119 * 120 * <p> 121 * <strong>Merging</strong> 122 * 123 * <p> 124 * The full <code>Config</code> for your application can be constructed using 125 * the associative operation {@link Config#withFallback(ConfigMergeable)}. If 126 * you use {@link ConfigFactory#load()} (recommended), it merges system 127 * properties over the top of <code>application.conf</code> over the top of 128 * <code>reference.conf</code>, using <code>withFallback</code>. You can add in 129 * additional sources of configuration in the same way (usually, custom layers 130 * should go either just above or just below <code>application.conf</code>, 131 * keeping <code>reference.conf</code> at the bottom and system properties at 132 * the top). 133 * 134 * <p> 135 * <strong>Serialization</strong> 136 * 137 * <p> 138 * Convert a <code>Config</code> to a JSON or HOCON string by calling 139 * {@link ConfigObject#render()} on the root object, 140 * <code>myConfig.root().render()</code>. There's also a variant 141 * {@link ConfigObject#render(ConfigRenderOptions)} which allows you to control 142 * the format of the rendered string. (See {@link ConfigRenderOptions}.) Note 143 * that <code>Config</code> does not remember the formatting of the original 144 * file, so if you load, modify, and re-save a config file, it will be 145 * substantially reformatted. 146 * 147 * <p> 148 * As an alternative to {@link ConfigObject#render()}, the 149 * <code>toString()</code> method produces a debug-output-oriented 150 * representation (which is not valid JSON). 151 * 152 * <p> 153 * Java serialization is supported as well for <code>Config</code> and all 154 * subtypes of <code>ConfigValue</code>. 155 * 156 * <p> 157 * <strong>This is an interface but don't implement it yourself</strong> 158 * 159 * <p> 160 * <em>Do not implement {@code Config}</em>; it should only be implemented by 161 * the config library. Arbitrary implementations will not work because the 162 * library internals assume a specific concrete implementation. Also, this 163 * interface is likely to grow new methods over time, so third-party 164 * implementations will break. 165 */ 166public interface Config extends ConfigMergeable { 167 /** 168 * Gets the {@code Config} as a tree of {@link ConfigObject}. This is a 169 * constant-time operation (it is not proportional to the number of values 170 * in the {@code Config}). 171 * 172 * @return the root object in the configuration 173 */ 174 ConfigObject root(); 175 176 /** 177 * Gets the origin of the {@code Config}, which may be a file, or a file 178 * with a line number, or just a descriptive phrase. 179 * 180 * @return the origin of the {@code Config} for use in error messages 181 */ 182 ConfigOrigin origin(); 183 184 @Override 185 Config withFallback(ConfigMergeable other); 186 187 /** 188 * Returns a replacement config with all substitutions (the 189 * <code>${foo.bar}</code> syntax, see <a 190 * href="https://github.com/typesafehub/config/blob/master/HOCON.md">the 191 * spec</a>) resolved. Substitutions are looked up using this 192 * <code>Config</code> as the root object, that is, a substitution 193 * <code>${foo.bar}</code> will be replaced with the result of 194 * <code>getValue("foo.bar")</code>. 195 * 196 * <p> 197 * This method uses {@link ConfigResolveOptions#defaults()}, there is 198 * another variant {@link Config#resolve(ConfigResolveOptions)} which lets 199 * you specify non-default options. 200 * 201 * <p> 202 * A given {@link Config} must be resolved before using it to retrieve 203 * config values, but ideally should be resolved one time for your entire 204 * stack of fallbacks (see {@link Config#withFallback}). Otherwise, some 205 * substitutions that could have resolved with all fallbacks available may 206 * not resolve, which will be potentially confusing for your application's 207 * users. 208 * 209 * <p> 210 * <code>resolve()</code> should be invoked on root config objects, rather 211 * than on a subtree (a subtree is the result of something like 212 * <code>config.getConfig("foo")</code>). The problem with 213 * <code>resolve()</code> on a subtree is that substitutions are relative to 214 * the root of the config and the subtree will have no way to get values 215 * from the root. For example, if you did 216 * <code>config.getConfig("foo").resolve()</code> on the below config file, 217 * it would not work: 218 * 219 * <pre> 220 * common-value = 10 221 * foo { 222 * whatever = ${common-value} 223 * } 224 * </pre> 225 * 226 * <p> 227 * Many methods on {@link ConfigFactory} such as 228 * {@link ConfigFactory#load()} automatically resolve the loaded 229 * <code>Config</code> on the loaded stack of config files. 230 * 231 * <p> 232 * Resolving an already-resolved config is a harmless no-op, but again, it 233 * is best to resolve an entire stack of fallbacks (such as all your config 234 * files combined) rather than resolving each one individually. 235 * 236 * @return an immutable object with substitutions resolved 237 * @throws ConfigException.UnresolvedSubstitution 238 * if any substitutions refer to nonexistent paths 239 * @throws ConfigException 240 * some other config exception if there are other problems 241 */ 242 Config resolve(); 243 244 /** 245 * Like {@link Config#resolve()} but allows you to specify non-default 246 * options. 247 * 248 * @param options 249 * resolve options 250 * @return the resolved <code>Config</code> (may be only partially resolved if options are set to allow unresolved) 251 */ 252 Config resolve(ConfigResolveOptions options); 253 254 /** 255 * Checks whether the config is completely resolved. After a successful call 256 * to {@link Config#resolve()} it will be completely resolved, but after 257 * calling {@link Config#resolve(ConfigResolveOptions)} with 258 * <code>allowUnresolved</code> set in the options, it may or may not be 259 * completely resolved. A newly-loaded config may or may not be completely 260 * resolved depending on whether there were substitutions present in the 261 * file. 262 * 263 * @return true if there are no unresolved substitutions remaining in this 264 * configuration. 265 * @since 1.2.0 266 */ 267 boolean isResolved(); 268 269 /** 270 * Like {@link Config#resolve()} except that substitution values are looked 271 * up in the given source, rather than in this instance. This is a 272 * special-purpose method which doesn't make sense to use in most cases; 273 * it's only needed if you're constructing some sort of app-specific custom 274 * approach to configuration. The more usual approach if you have a source 275 * of substitution values would be to merge that source into your config 276 * stack using {@link Config#withFallback} and then resolve. 277 * <p> 278 * Note that this method does NOT look in this instance for substitution 279 * values. If you want to do that, you could either merge this instance into 280 * your value source using {@link Config#withFallback}, or you could resolve 281 * multiple times with multiple sources (using 282 * {@link ConfigResolveOptions#setAllowUnresolved(boolean)} so the partial 283 * resolves don't fail). 284 * 285 * @param source 286 * configuration to pull values from 287 * @return an immutable object with substitutions resolved 288 * @throws ConfigException.UnresolvedSubstitution 289 * if any substitutions refer to paths which are not in the 290 * source 291 * @throws ConfigException 292 * some other config exception if there are other problems 293 * @since 1.2.0 294 */ 295 Config resolveWith(Config source); 296 297 /** 298 * Like {@link Config#resolveWith(Config)} but allows you to specify 299 * non-default options. 300 * 301 * @param source 302 * source configuration to pull values from 303 * @param options 304 * resolve options 305 * @return the resolved <code>Config</code> (may be only partially resolved 306 * if options are set to allow unresolved) 307 * @since 1.2.0 308 */ 309 Config resolveWith(Config source, ConfigResolveOptions options); 310 311 /** 312 * Validates this config against a reference config, throwing an exception 313 * if it is invalid. The purpose of this method is to "fail early" with a 314 * comprehensive list of problems; in general, anything this method can find 315 * would be detected later when trying to use the config, but it's often 316 * more user-friendly to fail right away when loading the config. 317 * 318 * <p> 319 * Using this method is always optional, since you can "fail late" instead. 320 * 321 * <p> 322 * You must restrict validation to paths you "own" (those whose meaning are 323 * defined by your code module). If you validate globally, you may trigger 324 * errors about paths that happen to be in the config but have nothing to do 325 * with your module. It's best to allow the modules owning those paths to 326 * validate them. Also, if every module validates only its own stuff, there 327 * isn't as much redundant work being done. 328 * 329 * <p> 330 * If no paths are specified in <code>checkValid()</code>'s parameter list, 331 * validation is for the entire config. 332 * 333 * <p> 334 * If you specify paths that are not in the reference config, those paths 335 * are ignored. (There's nothing to validate.) 336 * 337 * <p> 338 * Here's what validation involves: 339 * 340 * <ul> 341 * <li>All paths found in the reference config must be present in this 342 * config or an exception will be thrown. 343 * <li> 344 * Some changes in type from the reference config to this config will cause 345 * an exception to be thrown. Not all potential type problems are detected, 346 * in particular it's assumed that strings are compatible with everything 347 * except objects and lists. This is because string types are often "really" 348 * some other type (system properties always start out as strings, or a 349 * string like "5ms" could be used with {@link #getMilliseconds}). Also, 350 * it's allowed to set any type to null or override null with any type. 351 * <li> 352 * Any unresolved substitutions in this config will cause a validation 353 * failure; both the reference config and this config should be resolved 354 * before validation. If the reference config is unresolved, it's a bug in 355 * the caller of this method. 356 * </ul> 357 * 358 * <p> 359 * If you want to allow a certain setting to have a flexible type (or 360 * otherwise want validation to be looser for some settings), you could 361 * either remove the problematic setting from the reference config provided 362 * to this method, or you could intercept the validation exception and 363 * screen out certain problems. Of course, this will only work if all other 364 * callers of this method are careful to restrict validation to their own 365 * paths, as they should be. 366 * 367 * <p> 368 * If validation fails, the thrown exception contains a list of all problems 369 * found. See {@link ConfigException.ValidationFailed#problems}. The 370 * exception's <code>getMessage()</code> will have all the problems 371 * concatenated into one huge string, as well. 372 * 373 * <p> 374 * Again, <code>checkValid()</code> can't guess every domain-specific way a 375 * setting can be invalid, so some problems may arise later when attempting 376 * to use the config. <code>checkValid()</code> is limited to reporting 377 * generic, but common, problems such as missing settings and blatant type 378 * incompatibilities. 379 * 380 * @param reference 381 * a reference configuration 382 * @param restrictToPaths 383 * only validate values underneath these paths that your code 384 * module owns and understands 385 * @throws ConfigException.ValidationFailed 386 * if there are any validation issues 387 * @throws ConfigException.NotResolved 388 * if this config is not resolved 389 * @throws ConfigException.BugOrBroken 390 * if the reference config is unresolved or caller otherwise 391 * misuses the API 392 */ 393 void checkValid(Config reference, String... restrictToPaths); 394 395 /** 396 * Checks whether a value is present and non-null at the given path. This 397 * differs in two ways from {@code Map.containsKey()} as implemented by 398 * {@link ConfigObject}: it looks for a path expression, not a key; and it 399 * returns false for null values, while {@code containsKey()} returns true 400 * indicating that the object contains a null value for the key. 401 * 402 * <p> 403 * If a path exists according to {@link #hasPath(String)}, then 404 * {@link #getValue(String)} will never throw an exception. However, the 405 * typed getters, such as {@link #getInt(String)}, will still throw if the 406 * value is not convertible to the requested type. 407 * 408 * <p> 409 * Note that path expressions have a syntax and sometimes require quoting 410 * (see {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}). 411 * 412 * @param path 413 * the path expression 414 * @return true if a non-null value is present at the path 415 * @throws ConfigException.BadPath 416 * if the path expression is invalid 417 */ 418 boolean hasPath(String path); 419 420 /** 421 * Checks whether a value is present at the given path, even 422 * if the value is null. Most of the getters on 423 * <code>Config</code> will throw if you try to get a null 424 * value, so if you plan to call {@link #getValue(String)}, 425 * {@link #getInt(String)}, or another getter you may want to 426 * use plain {@link #hasPath(String)} rather than this method. 427 * 428 * <p> 429 * To handle all three cases (unset, null, and a non-null value) 430 * the code might look like: 431 * <pre><code> 432 * if (config.hasPathOrNull(path)) { 433 * if (config.getIsNull(path)) { 434 * // handle null setting 435 * } else { 436 * // get and use non-null setting 437 * } 438 * } else { 439 * // handle entirely unset path 440 * } 441 * </code></pre> 442 * 443 * <p> However, the usual thing is to allow entirely unset 444 * paths to be a bug that throws an exception (because you set 445 * a default in your <code>reference.conf</code>), so in that 446 * case it's OK to call {@link #getIsNull(String)} without 447 * checking <code>hasPathOrNull</code> first. 448 * 449 * <p> 450 * Note that path expressions have a syntax and sometimes require quoting 451 * (see {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}). 452 * 453 * @param path 454 * the path expression 455 * @return true if a value is present at the path, even if the value is null 456 * @throws ConfigException.BadPath 457 * if the path expression is invalid 458 */ 459 boolean hasPathOrNull(String path); 460 461 /** 462 * Returns true if the {@code Config}'s root object contains no key-value 463 * pairs. 464 * 465 * @return true if the configuration is empty 466 */ 467 boolean isEmpty(); 468 469 /** 470 * Returns the set of path-value pairs, excluding any null values, found by 471 * recursing {@link #root() the root object}. Note that this is very 472 * different from <code>root().entrySet()</code> which returns the set of 473 * immediate-child keys in the root object and includes null values. 474 * <p> 475 * Entries contain <em>path expressions</em> meaning there may be quoting 476 * and escaping involved. Parse path expressions with 477 * {@link ConfigUtil#splitPath}. 478 * <p> 479 * Because a <code>Config</code> is conceptually a single-level map from 480 * paths to values, there will not be any {@link ConfigObject} values in the 481 * entries (that is, all entries represent leaf nodes). Use 482 * {@link ConfigObject} rather than <code>Config</code> if you want a tree. 483 * (OK, this is a slight lie: <code>Config</code> entries may contain 484 * {@link ConfigList} and the lists may contain objects. But no objects are 485 * directly included as entry values.) 486 * 487 * @return set of paths with non-null values, built up by recursing the 488 * entire tree of {@link ConfigObject} and creating an entry for 489 * each leaf value. 490 */ 491 Set<Map.Entry<String, ConfigValue>> entrySet(); 492 493 /** 494 * Checks whether a value is set to null at the given path, 495 * but throws an exception if the value is entirely 496 * unset. This method will not throw if {@link 497 * #hasPathOrNull(String)} returned true for the same path, so 498 * to avoid any possible exception check 499 * <code>hasPathOrNull()</code> first. However, an exception 500 * for unset paths will usually be the right thing (because a 501 * <code>reference.conf</code> should exist that has the path 502 * set, the path should never be unset unless something is 503 * broken). 504 * 505 * <p> 506 * Note that path expressions have a syntax and sometimes require quoting 507 * (see {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}). 508 * 509 * @param path 510 * the path expression 511 * @return true if the value exists and is null, false if it 512 * exists and is not null 513 * @throws ConfigException.BadPath 514 * if the path expression is invalid 515 * @throws ConfigException.Missing 516 * if value is not set at all 517 */ 518 boolean getIsNull(String path); 519 520 /** 521 * 522 * @param path 523 * path expression 524 * @return the boolean value at the requested path 525 * @throws ConfigException.Missing 526 * if value is absent or null 527 * @throws ConfigException.WrongType 528 * if value is not convertible to boolean 529 */ 530 boolean getBoolean(String path); 531 532 /** 533 * @param path 534 * path expression 535 * @return the numeric value at the requested path 536 * @throws ConfigException.Missing 537 * if value is absent or null 538 * @throws ConfigException.WrongType 539 * if value is not convertible to a number 540 */ 541 Number getNumber(String path); 542 543 /** 544 * Gets the integer at the given path. If the value at the 545 * path has a fractional (floating point) component, it 546 * will be discarded and only the integer part will be 547 * returned (it works like a "narrowing primitive conversion" 548 * in the Java language specification). 549 * 550 * @param path 551 * path expression 552 * @return the 32-bit integer value at the requested path 553 * @throws ConfigException.Missing 554 * if value is absent or null 555 * @throws ConfigException.WrongType 556 * if value is not convertible to an int (for example it is out 557 * of range, or it's a boolean value) 558 */ 559 int getInt(String path); 560 561 /** 562 * Gets the long integer at the given path. If the value at 563 * the path has a fractional (floating point) component, it 564 * will be discarded and only the integer part will be 565 * returned (it works like a "narrowing primitive conversion" 566 * in the Java language specification). 567 * 568 * @param path 569 * path expression 570 * @return the 64-bit long value at the requested path 571 * @throws ConfigException.Missing 572 * if value is absent or null 573 * @throws ConfigException.WrongType 574 * if value is not convertible to a long 575 */ 576 long getLong(String path); 577 578 /** 579 * @param path 580 * path expression 581 * @return the floating-point value at the requested path 582 * @throws ConfigException.Missing 583 * if value is absent or null 584 * @throws ConfigException.WrongType 585 * if value is not convertible to a double 586 */ 587 double getDouble(String path); 588 589 /** 590 * @param path 591 * path expression 592 * @return the string value at the requested path 593 * @throws ConfigException.Missing 594 * if value is absent or null 595 * @throws ConfigException.WrongType 596 * if value is not convertible to a string 597 */ 598 String getString(String path); 599 600 /** 601 * @param path 602 * path expression 603 * @return the {@link ConfigObject} value at the requested path 604 * @throws ConfigException.Missing 605 * if value is absent or null 606 * @throws ConfigException.WrongType 607 * if value is not convertible to an object 608 */ 609 ConfigObject getObject(String path); 610 611 /** 612 * @param path 613 * path expression 614 * @return the nested {@code Config} value at the requested path 615 * @throws ConfigException.Missing 616 * if value is absent or null 617 * @throws ConfigException.WrongType 618 * if value is not convertible to a Config 619 */ 620 Config getConfig(String path); 621 622 /** 623 * Gets the value at the path as an unwrapped Java boxed value ( 624 * {@link java.lang.Boolean Boolean}, {@link java.lang.Integer Integer}, and 625 * so on - see {@link ConfigValue#unwrapped()}). 626 * 627 * @param path 628 * path expression 629 * @return the unwrapped value at the requested path 630 * @throws ConfigException.Missing 631 * if value is absent or null 632 */ 633 Object getAnyRef(String path); 634 635 /** 636 * Gets the value at the given path, unless the value is a 637 * null value or missing, in which case it throws just like 638 * the other getters. Use {@code get()} on the {@link 639 * Config#root()} object (or other object in the tree) if you 640 * want an unprocessed value. 641 * 642 * @param path 643 * path expression 644 * @return the value at the requested path 645 * @throws ConfigException.Missing 646 * if value is absent or null 647 */ 648 ConfigValue getValue(String path); 649 650 /** 651 * Gets a value as a size in bytes (parses special strings like "128M"). If 652 * the value is already a number, then it's left alone; if it's a string, 653 * it's parsed understanding unit suffixes such as "128K", as documented in 654 * the <a 655 * href="https://github.com/typesafehub/config/blob/master/HOCON.md">the 656 * spec</a>. 657 * 658 * @param path 659 * path expression 660 * @return the value at the requested path, in bytes 661 * @throws ConfigException.Missing 662 * if value is absent or null 663 * @throws ConfigException.WrongType 664 * if value is not convertible to Long or String 665 * @throws ConfigException.BadValue 666 * if value cannot be parsed as a size in bytes 667 */ 668 Long getBytes(String path); 669 670 /** 671 * Gets a value as an amount of memory (parses special strings like "128M"). If 672 * the value is already a number, then it's left alone; if it's a string, 673 * it's parsed understanding unit suffixes such as "128K", as documented in 674 * the <a 675 * href="https://github.com/typesafehub/config/blob/master/HOCON.md">the 676 * spec</a>. 677 * 678 * @since 1.3.0 679 * 680 * @param path 681 * path expression 682 * @return the value at the requested path, in bytes 683 * @throws ConfigException.Missing 684 * if value is absent or null 685 * @throws ConfigException.WrongType 686 * if value is not convertible to Long or String 687 * @throws ConfigException.BadValue 688 * if value cannot be parsed as a size in bytes 689 */ 690 ConfigMemorySize getMemorySize(String path); 691 692 /** 693 * Get value as a duration in milliseconds. If the value is already a 694 * number, then it's left alone; if it's a string, it's parsed understanding 695 * units suffixes like "10m" or "5ns" as documented in the <a 696 * href="https://github.com/typesafehub/config/blob/master/HOCON.md">the 697 * spec</a>. 698 * 699 * @deprecated As of release 1.1, replaced by {@link #getDuration(String, TimeUnit)} 700 * 701 * @param path 702 * path expression 703 * @return the duration value at the requested path, in milliseconds 704 * @throws ConfigException.Missing 705 * if value is absent or null 706 * @throws ConfigException.WrongType 707 * if value is not convertible to Long or String 708 * @throws ConfigException.BadValue 709 * if value cannot be parsed as a number of milliseconds 710 */ 711 @Deprecated Long getMilliseconds(String path); 712 713 /** 714 * Get value as a duration in nanoseconds. If the value is already a number 715 * it's taken as milliseconds and converted to nanoseconds. If it's a 716 * string, it's parsed understanding unit suffixes, as for 717 * {@link #getDuration(String, TimeUnit)}. 718 * 719 * @deprecated As of release 1.1, replaced by {@link #getDuration(String, TimeUnit)} 720 * 721 * @param path 722 * path expression 723 * @return the duration value at the requested path, in nanoseconds 724 * @throws ConfigException.Missing 725 * if value is absent or null 726 * @throws ConfigException.WrongType 727 * if value is not convertible to Long or String 728 * @throws ConfigException.BadValue 729 * if value cannot be parsed as a number of nanoseconds 730 */ 731 @Deprecated Long getNanoseconds(String path); 732 733 /** 734 * Gets a value as a duration in a specified 735 * {@link java.util.concurrent.TimeUnit TimeUnit}. If the value is already a 736 * number, then it's taken as milliseconds and then converted to the 737 * requested TimeUnit; if it's a string, it's parsed understanding units 738 * suffixes like "10m" or "5ns" as documented in the <a 739 * href="https://github.com/typesafehub/config/blob/master/HOCON.md">the 740 * spec</a>. 741 * 742 * @since 1.2.0 743 * 744 * @param path 745 * path expression 746 * @param unit 747 * convert the return value to this time unit 748 * @return the duration value at the requested path, in the given TimeUnit 749 * @throws ConfigException.Missing 750 * if value is absent or null 751 * @throws ConfigException.WrongType 752 * if value is not convertible to Long or String 753 * @throws ConfigException.BadValue 754 * if value cannot be parsed as a number of the given TimeUnit 755 */ 756 long getDuration(String path, TimeUnit unit); 757 758 /** 759 * Gets a value as a java.time.Duration. If the value is 760 * already a number, then it's taken as milliseconds; if it's 761 * a string, it's parsed understanding units suffixes like 762 * "10m" or "5ns" as documented in the <a 763 * href="https://github.com/typesafehub/config/blob/master/HOCON.md">the 764 * spec</a>. This method never returns null. 765 * 766 * @since 1.3.0 767 * 768 * @param path 769 * path expression 770 * @return the duration value at the requested path 771 * @throws ConfigException.Missing 772 * if value is absent or null 773 * @throws ConfigException.WrongType 774 * if value is not convertible to Long or String 775 * @throws ConfigException.BadValue 776 * if value cannot be parsed as a number of the given TimeUnit 777 */ 778 Duration getDuration(String path); 779 780 /** 781 * Gets a list value (with any element type) as a {@link ConfigList}, which 782 * implements {@code java.util.List<ConfigValue>}. Throws if the path is 783 * unset or null. 784 * 785 * @param path 786 * the path to the list value. 787 * @return the {@link ConfigList} at the path 788 * @throws ConfigException.Missing 789 * if value is absent or null 790 * @throws ConfigException.WrongType 791 * if value is not convertible to a ConfigList 792 */ 793 ConfigList getList(String path); 794 795 /** 796 * Gets a list value with boolean elements. Throws if the 797 * path is unset or null or not a list or contains values not 798 * convertible to boolean. 799 * 800 * @param path 801 * the path to the list value. 802 * @return the list at the path 803 * @throws ConfigException.Missing 804 * if value is absent or null 805 * @throws ConfigException.WrongType 806 * if value is not convertible to a list of booleans 807 */ 808 List<Boolean> getBooleanList(String path); 809 810 /** 811 * Gets a list value with number elements. Throws if the 812 * path is unset or null or not a list or contains values not 813 * convertible to number. 814 * 815 * @param path 816 * the path to the list value. 817 * @return the list at the path 818 * @throws ConfigException.Missing 819 * if value is absent or null 820 * @throws ConfigException.WrongType 821 * if value is not convertible to a list of numbers 822 */ 823 List<Number> getNumberList(String path); 824 825 /** 826 * Gets a list value with int elements. Throws if the 827 * path is unset or null or not a list or contains values not 828 * convertible to int. 829 * 830 * @param path 831 * the path to the list value. 832 * @return the list at the path 833 * @throws ConfigException.Missing 834 * if value is absent or null 835 * @throws ConfigException.WrongType 836 * if value is not convertible to a list of ints 837 */ 838 List<Integer> getIntList(String path); 839 840 /** 841 * Gets a list value with long elements. Throws if the 842 * path is unset or null or not a list or contains values not 843 * convertible to long. 844 * 845 * @param path 846 * the path to the list value. 847 * @return the list at the path 848 * @throws ConfigException.Missing 849 * if value is absent or null 850 * @throws ConfigException.WrongType 851 * if value is not convertible to a list of longs 852 */ 853 List<Long> getLongList(String path); 854 855 /** 856 * Gets a list value with double elements. Throws if the 857 * path is unset or null or not a list or contains values not 858 * convertible to double. 859 * 860 * @param path 861 * the path to the list value. 862 * @return the list at the path 863 * @throws ConfigException.Missing 864 * if value is absent or null 865 * @throws ConfigException.WrongType 866 * if value is not convertible to a list of doubles 867 */ 868 List<Double> getDoubleList(String path); 869 870 /** 871 * Gets a list value with string elements. Throws if the 872 * path is unset or null or not a list or contains values not 873 * convertible to string. 874 * 875 * @param path 876 * the path to the list value. 877 * @return the list at the path 878 * @throws ConfigException.Missing 879 * if value is absent or null 880 * @throws ConfigException.WrongType 881 * if value is not convertible to a list of strings 882 */ 883 List<String> getStringList(String path); 884 885 /** 886 * Gets a list value with object elements. Throws if the 887 * path is unset or null or not a list or contains values not 888 * convertible to <code>ConfigObject</code>. 889 * 890 * @param path 891 * the path to the list value. 892 * @return the list at the path 893 * @throws ConfigException.Missing 894 * if value is absent or null 895 * @throws ConfigException.WrongType 896 * if value is not convertible to a list of objects 897 */ 898 List<? extends ConfigObject> getObjectList(String path); 899 900 /** 901 * Gets a list value with <code>Config</code> elements. 902 * Throws if the path is unset or null or not a list or 903 * contains values not convertible to <code>Config</code>. 904 * 905 * @param path 906 * the path to the list value. 907 * @return the list at the path 908 * @throws ConfigException.Missing 909 * if value is absent or null 910 * @throws ConfigException.WrongType 911 * if value is not convertible to a list of configs 912 */ 913 List<? extends Config> getConfigList(String path); 914 915 /** 916 * Gets a list value with any kind of elements. Throws if the 917 * path is unset or null or not a list. Each element is 918 * "unwrapped" (see {@link ConfigValue#unwrapped()}). 919 * 920 * @param path 921 * the path to the list value. 922 * @return the list at the path 923 * @throws ConfigException.Missing 924 * if value is absent or null 925 * @throws ConfigException.WrongType 926 * if value is not convertible to a list 927 */ 928 List<? extends Object> getAnyRefList(String path); 929 930 /** 931 * Gets a list value with elements representing a size in 932 * bytes. Throws if the path is unset or null or not a list 933 * or contains values not convertible to memory sizes. 934 * 935 * @param path 936 * the path to the list value. 937 * @return the list at the path 938 * @throws ConfigException.Missing 939 * if value is absent or null 940 * @throws ConfigException.WrongType 941 * if value is not convertible to a list of memory sizes 942 */ 943 List<Long> getBytesList(String path); 944 945 /** 946 * Gets a list, converting each value in the list to a memory size, using the 947 * same rules as {@link #getMemorySize(String)}. 948 * 949 * @since 1.3.0 950 * @param path 951 * a path expression 952 * @return list of memory sizes 953 * @throws ConfigException.Missing 954 * if value is absent or null 955 * @throws ConfigException.WrongType 956 * if value is not convertible to a list of memory sizes 957 */ 958 List<ConfigMemorySize> getMemorySizeList(String path); 959 960 /** 961 * @deprecated As of release 1.1, replaced by {@link #getDurationList(String, TimeUnit)} 962 * @param path the path 963 * @return list of millisecond values 964 */ 965 @Deprecated List<Long> getMillisecondsList(String path); 966 967 /** 968 * @deprecated As of release 1.1, replaced by {@link #getDurationList(String, TimeUnit)} 969 * @param path the path 970 * @return list of nanosecond values 971 */ 972 @Deprecated List<Long> getNanosecondsList(String path); 973 974 /** 975 * Gets a list, converting each value in the list to a duration, using the 976 * same rules as {@link #getDuration(String, TimeUnit)}. 977 * 978 * @since 1.2.0 979 * @param path 980 * a path expression 981 * @param unit 982 * time units of the returned values 983 * @return list of durations, in the requested units 984 */ 985 List<Long> getDurationList(String path, TimeUnit unit); 986 987 /** 988 * Gets a list, converting each value in the list to a duration, using the 989 * same rules as {@link #getDuration(String)}. 990 * 991 * @since 1.3.0 992 * @param path 993 * a path expression 994 * @return list of durations 995 */ 996 List<Duration> getDurationList(String path); 997 998 /** 999 * Clone the config with only the given path (and its children) retained; 1000 * all sibling paths are removed. 1001 * <p> 1002 * Note that path expressions have a syntax and sometimes require quoting 1003 * (see {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}). 1004 * 1005 * @param path 1006 * path to keep 1007 * @return a copy of the config minus all paths except the one specified 1008 */ 1009 Config withOnlyPath(String path); 1010 1011 /** 1012 * Clone the config with the given path removed. 1013 * <p> 1014 * Note that path expressions have a syntax and sometimes require quoting 1015 * (see {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}). 1016 * 1017 * @param path 1018 * path expression to remove 1019 * @return a copy of the config minus the specified path 1020 */ 1021 Config withoutPath(String path); 1022 1023 /** 1024 * Places the config inside another {@code Config} at the given path. 1025 * <p> 1026 * Note that path expressions have a syntax and sometimes require quoting 1027 * (see {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}). 1028 * 1029 * @param path 1030 * path expression to store this config at. 1031 * @return a {@code Config} instance containing this config at the given 1032 * path. 1033 */ 1034 Config atPath(String path); 1035 1036 /** 1037 * Places the config inside a {@code Config} at the given key. See also 1038 * atPath(). Note that a key is NOT a path expression (see 1039 * {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}). 1040 * 1041 * @param key 1042 * key to store this config at. 1043 * @return a {@code Config} instance containing this config at the given 1044 * key. 1045 */ 1046 Config atKey(String key); 1047 1048 /** 1049 * Returns a {@code Config} based on this one, but with the given path set 1050 * to the given value. Does not modify this instance (since it's immutable). 1051 * If the path already has a value, that value is replaced. To remove a 1052 * value, use withoutPath(). 1053 * <p> 1054 * Note that path expressions have a syntax and sometimes require quoting 1055 * (see {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}). 1056 * 1057 * @param path 1058 * path expression for the value's new location 1059 * @param value 1060 * value at the new path 1061 * @return the new instance with the new map entry 1062 */ 1063 Config withValue(String path, ConfigValue value); 1064}