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