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 enumClass 602 * an enum class 603 * @param <T> 604 * a generic denoting a specific type of enum 605 * @param path 606 * path expression 607 * @return the {@code Enum} value at the requested path 608 * of the requested enum class 609 * @throws ConfigException.Missing 610 * if value is absent or null 611 * @throws ConfigException.WrongType 612 * if value is not convertible to an Enum 613 */ 614 public <T extends Enum<T>> T getEnum(Class<T> enumClass, String path); 615 616 /** 617 * @param path 618 * path expression 619 * @return the {@link ConfigObject} value at the requested path 620 * @throws ConfigException.Missing 621 * if value is absent or null 622 * @throws ConfigException.WrongType 623 * if value is not convertible to an object 624 */ 625 ConfigObject getObject(String path); 626 627 /** 628 * @param path 629 * path expression 630 * @return the nested {@code Config} value at the requested path 631 * @throws ConfigException.Missing 632 * if value is absent or null 633 * @throws ConfigException.WrongType 634 * if value is not convertible to a Config 635 */ 636 Config getConfig(String path); 637 638 /** 639 * Gets the value at the path as an unwrapped Java boxed value ( 640 * {@link java.lang.Boolean Boolean}, {@link java.lang.Integer Integer}, and 641 * so on - see {@link ConfigValue#unwrapped()}). 642 * 643 * @param path 644 * path expression 645 * @return the unwrapped value at the requested path 646 * @throws ConfigException.Missing 647 * if value is absent or null 648 */ 649 Object getAnyRef(String path); 650 651 /** 652 * Gets the value at the given path, unless the value is a 653 * null value or missing, in which case it throws just like 654 * the other getters. Use {@code get()} on the {@link 655 * Config#root()} object (or other object in the tree) if you 656 * want an unprocessed value. 657 * 658 * @param path 659 * path expression 660 * @return the value at the requested path 661 * @throws ConfigException.Missing 662 * if value is absent or null 663 */ 664 ConfigValue getValue(String path); 665 666 /** 667 * Gets a value as a size in bytes (parses special strings like "128M"). If 668 * the value is already a number, then it's left alone; if it's a string, 669 * it's parsed understanding unit suffixes such as "128K", as documented in 670 * the <a 671 * href="https://github.com/typesafehub/config/blob/master/HOCON.md">the 672 * spec</a>. 673 * 674 * @param path 675 * path expression 676 * @return the value at the requested path, in bytes 677 * @throws ConfigException.Missing 678 * if value is absent or null 679 * @throws ConfigException.WrongType 680 * if value is not convertible to Long or String 681 * @throws ConfigException.BadValue 682 * if value cannot be parsed as a size in bytes 683 */ 684 Long getBytes(String path); 685 686 /** 687 * Gets a value as an amount of memory (parses special strings like "128M"). If 688 * the value is already a number, then it's left alone; if it's a string, 689 * it's parsed understanding unit suffixes such as "128K", as documented in 690 * the <a 691 * href="https://github.com/typesafehub/config/blob/master/HOCON.md">the 692 * spec</a>. 693 * 694 * @since 1.3.0 695 * 696 * @param path 697 * path expression 698 * @return the value at the requested path, in bytes 699 * @throws ConfigException.Missing 700 * if value is absent or null 701 * @throws ConfigException.WrongType 702 * if value is not convertible to Long or String 703 * @throws ConfigException.BadValue 704 * if value cannot be parsed as a size in bytes 705 */ 706 ConfigMemorySize getMemorySize(String path); 707 708 /** 709 * Get value as a duration in milliseconds. If the value is already a 710 * number, then it's left alone; if it's a string, it's parsed understanding 711 * units suffixes like "10m" or "5ns" as documented in the <a 712 * href="https://github.com/typesafehub/config/blob/master/HOCON.md">the 713 * spec</a>. 714 * 715 * @deprecated As of release 1.1, replaced by {@link #getDuration(String, TimeUnit)} 716 * 717 * @param path 718 * path expression 719 * @return the duration value at the requested path, in milliseconds 720 * @throws ConfigException.Missing 721 * if value is absent or null 722 * @throws ConfigException.WrongType 723 * if value is not convertible to Long or String 724 * @throws ConfigException.BadValue 725 * if value cannot be parsed as a number of milliseconds 726 */ 727 @Deprecated Long getMilliseconds(String path); 728 729 /** 730 * Get value as a duration in nanoseconds. If the value is already a number 731 * it's taken as milliseconds and converted to nanoseconds. If it's a 732 * string, it's parsed understanding unit suffixes, as for 733 * {@link #getDuration(String, TimeUnit)}. 734 * 735 * @deprecated As of release 1.1, replaced by {@link #getDuration(String, TimeUnit)} 736 * 737 * @param path 738 * path expression 739 * @return the duration value at the requested path, in nanoseconds 740 * @throws ConfigException.Missing 741 * if value is absent or null 742 * @throws ConfigException.WrongType 743 * if value is not convertible to Long or String 744 * @throws ConfigException.BadValue 745 * if value cannot be parsed as a number of nanoseconds 746 */ 747 @Deprecated Long getNanoseconds(String path); 748 749 /** 750 * Gets a value as a duration in a specified 751 * {@link java.util.concurrent.TimeUnit TimeUnit}. If the value is already a 752 * number, then it's taken as milliseconds and then converted to the 753 * requested TimeUnit; if it's a string, it's parsed understanding units 754 * suffixes like "10m" or "5ns" as documented in the <a 755 * href="https://github.com/typesafehub/config/blob/master/HOCON.md">the 756 * spec</a>. 757 * 758 * @since 1.2.0 759 * 760 * @param path 761 * path expression 762 * @param unit 763 * convert the return value to this time unit 764 * @return the duration value at the requested path, in the given TimeUnit 765 * @throws ConfigException.Missing 766 * if value is absent or null 767 * @throws ConfigException.WrongType 768 * if value is not convertible to Long or String 769 * @throws ConfigException.BadValue 770 * if value cannot be parsed as a number of the given TimeUnit 771 */ 772 long getDuration(String path, TimeUnit unit); 773 774 /** 775 * Gets a value as a java.time.Duration. If the value is 776 * already a number, then it's taken as milliseconds; if it's 777 * a string, it's parsed understanding units suffixes like 778 * "10m" or "5ns" as documented in the <a 779 * href="https://github.com/typesafehub/config/blob/master/HOCON.md">the 780 * spec</a>. This method never returns null. 781 * 782 * @since 1.3.0 783 * 784 * @param path 785 * path expression 786 * @return the duration value at the requested path 787 * @throws ConfigException.Missing 788 * if value is absent or null 789 * @throws ConfigException.WrongType 790 * if value is not convertible to Long or String 791 * @throws ConfigException.BadValue 792 * if value cannot be parsed as a number of the given TimeUnit 793 */ 794 Duration getDuration(String path); 795 796 /** 797 * Gets a list value (with any element type) as a {@link ConfigList}, which 798 * implements {@code java.util.List<ConfigValue>}. Throws if the path is 799 * unset or null. 800 * 801 * @param path 802 * the path to the list value. 803 * @return the {@link ConfigList} at the path 804 * @throws ConfigException.Missing 805 * if value is absent or null 806 * @throws ConfigException.WrongType 807 * if value is not convertible to a ConfigList 808 */ 809 ConfigList getList(String path); 810 811 /** 812 * Gets a list value with boolean elements. Throws if the 813 * path is unset or null or not a list or contains values not 814 * convertible to boolean. 815 * 816 * @param path 817 * the path to the list value. 818 * @return the list at the path 819 * @throws ConfigException.Missing 820 * if value is absent or null 821 * @throws ConfigException.WrongType 822 * if value is not convertible to a list of booleans 823 */ 824 List<Boolean> getBooleanList(String path); 825 826 /** 827 * Gets a list value with number elements. Throws if the 828 * path is unset or null or not a list or contains values not 829 * convertible to number. 830 * 831 * @param path 832 * the path to the list value. 833 * @return the list at the path 834 * @throws ConfigException.Missing 835 * if value is absent or null 836 * @throws ConfigException.WrongType 837 * if value is not convertible to a list of numbers 838 */ 839 List<Number> getNumberList(String path); 840 841 /** 842 * Gets a list value with int elements. Throws if the 843 * path is unset or null or not a list or contains values not 844 * convertible to int. 845 * 846 * @param path 847 * the path to the list value. 848 * @return the list at the path 849 * @throws ConfigException.Missing 850 * if value is absent or null 851 * @throws ConfigException.WrongType 852 * if value is not convertible to a list of ints 853 */ 854 List<Integer> getIntList(String path); 855 856 /** 857 * Gets a list value with long elements. Throws if the 858 * path is unset or null or not a list or contains values not 859 * convertible to long. 860 * 861 * @param path 862 * the path to the list value. 863 * @return the list at the path 864 * @throws ConfigException.Missing 865 * if value is absent or null 866 * @throws ConfigException.WrongType 867 * if value is not convertible to a list of longs 868 */ 869 List<Long> getLongList(String path); 870 871 /** 872 * Gets a list value with double elements. Throws if the 873 * path is unset or null or not a list or contains values not 874 * convertible to double. 875 * 876 * @param path 877 * the path to the list value. 878 * @return the list at the path 879 * @throws ConfigException.Missing 880 * if value is absent or null 881 * @throws ConfigException.WrongType 882 * if value is not convertible to a list of doubles 883 */ 884 List<Double> getDoubleList(String path); 885 886 /** 887 * Gets a list value with string elements. Throws if the 888 * path is unset or null or not a list or contains values not 889 * convertible to string. 890 * 891 * @param path 892 * the path to the list value. 893 * @return the list at the path 894 * @throws ConfigException.Missing 895 * if value is absent or null 896 * @throws ConfigException.WrongType 897 * if value is not convertible to a list of strings 898 */ 899 List<String> getStringList(String path); 900 901 /** 902 * Gets a list value with {@code Enum} elements. Throws if the 903 * path is unset or null or not a list or contains values not 904 * convertible to {@code Enum}. 905 * 906 * @param enumClass 907 * the enum class 908 * @param <T> 909 * a generic denoting a specific type of enum 910 * @param path 911 * the path to the list value. 912 * @return the list at the path 913 * @throws ConfigException.Missing 914 * if value is absent or null 915 * @throws ConfigException.WrongType 916 * if value is not convertible to a list of {@code Enum} 917 */ 918 <T extends Enum<T>> List<T> getEnumList(Class<T> enumClass, String path); 919 920 /** 921 * Gets a list value with object elements. Throws if the 922 * path is unset or null or not a list or contains values not 923 * convertible to <code>ConfigObject</code>. 924 * 925 * @param path 926 * the path to the list value. 927 * @return the list at the path 928 * @throws ConfigException.Missing 929 * if value is absent or null 930 * @throws ConfigException.WrongType 931 * if value is not convertible to a list of objects 932 */ 933 List<? extends ConfigObject> getObjectList(String path); 934 935 /** 936 * Gets a list value with <code>Config</code> elements. 937 * Throws if the path is unset or null or not a list or 938 * contains values not convertible to <code>Config</code>. 939 * 940 * @param path 941 * the path to the list value. 942 * @return the list at the path 943 * @throws ConfigException.Missing 944 * if value is absent or null 945 * @throws ConfigException.WrongType 946 * if value is not convertible to a list of configs 947 */ 948 List<? extends Config> getConfigList(String path); 949 950 /** 951 * Gets a list value with any kind of elements. Throws if the 952 * path is unset or null or not a list. Each element is 953 * "unwrapped" (see {@link ConfigValue#unwrapped()}). 954 * 955 * @param path 956 * the path to the list value. 957 * @return the list at the path 958 * @throws ConfigException.Missing 959 * if value is absent or null 960 * @throws ConfigException.WrongType 961 * if value is not convertible to a list 962 */ 963 List<? extends Object> getAnyRefList(String path); 964 965 /** 966 * Gets a list value with elements representing a size in 967 * bytes. Throws if the path is unset or null or not a list 968 * or contains values not convertible to memory sizes. 969 * 970 * @param path 971 * the path to the list value. 972 * @return the list at the path 973 * @throws ConfigException.Missing 974 * if value is absent or null 975 * @throws ConfigException.WrongType 976 * if value is not convertible to a list of memory sizes 977 */ 978 List<Long> getBytesList(String path); 979 980 /** 981 * Gets a list, converting each value in the list to a memory size, using the 982 * same rules as {@link #getMemorySize(String)}. 983 * 984 * @since 1.3.0 985 * @param path 986 * a path expression 987 * @return list of memory sizes 988 * @throws ConfigException.Missing 989 * if value is absent or null 990 * @throws ConfigException.WrongType 991 * if value is not convertible to a list of memory sizes 992 */ 993 List<ConfigMemorySize> getMemorySizeList(String path); 994 995 /** 996 * @deprecated As of release 1.1, replaced by {@link #getDurationList(String, TimeUnit)} 997 * @param path the path 998 * @return list of millisecond values 999 */ 1000 @Deprecated List<Long> getMillisecondsList(String path); 1001 1002 /** 1003 * @deprecated As of release 1.1, replaced by {@link #getDurationList(String, TimeUnit)} 1004 * @param path the path 1005 * @return list of nanosecond values 1006 */ 1007 @Deprecated List<Long> getNanosecondsList(String path); 1008 1009 /** 1010 * Gets a list, converting each value in the list to a duration, using the 1011 * same rules as {@link #getDuration(String, TimeUnit)}. 1012 * 1013 * @since 1.2.0 1014 * @param path 1015 * a path expression 1016 * @param unit 1017 * time units of the returned values 1018 * @return list of durations, in the requested units 1019 */ 1020 List<Long> getDurationList(String path, TimeUnit unit); 1021 1022 /** 1023 * Gets a list, converting each value in the list to a duration, using the 1024 * same rules as {@link #getDuration(String)}. 1025 * 1026 * @since 1.3.0 1027 * @param path 1028 * a path expression 1029 * @return list of durations 1030 */ 1031 List<Duration> getDurationList(String path); 1032 1033 /** 1034 * Clone the config with only the given path (and its children) retained; 1035 * all sibling paths are removed. 1036 * <p> 1037 * Note that path expressions have a syntax and sometimes require quoting 1038 * (see {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}). 1039 * 1040 * @param path 1041 * path to keep 1042 * @return a copy of the config minus all paths except the one specified 1043 */ 1044 Config withOnlyPath(String path); 1045 1046 /** 1047 * Clone the config with the given path removed. 1048 * <p> 1049 * Note that path expressions have a syntax and sometimes require quoting 1050 * (see {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}). 1051 * 1052 * @param path 1053 * path expression to remove 1054 * @return a copy of the config minus the specified path 1055 */ 1056 Config withoutPath(String path); 1057 1058 /** 1059 * Places the config inside another {@code Config} at the given path. 1060 * <p> 1061 * Note that path expressions have a syntax and sometimes require quoting 1062 * (see {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}). 1063 * 1064 * @param path 1065 * path expression to store this config at. 1066 * @return a {@code Config} instance containing this config at the given 1067 * path. 1068 */ 1069 Config atPath(String path); 1070 1071 /** 1072 * Places the config inside a {@code Config} at the given key. See also 1073 * atPath(). Note that a key is NOT a path expression (see 1074 * {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}). 1075 * 1076 * @param key 1077 * key to store this config at. 1078 * @return a {@code Config} instance containing this config at the given 1079 * key. 1080 */ 1081 Config atKey(String key); 1082 1083 /** 1084 * Returns a {@code Config} based on this one, but with the given path set 1085 * to the given value. Does not modify this instance (since it's immutable). 1086 * If the path already has a value, that value is replaced. To remove a 1087 * value, use withoutPath(). 1088 * <p> 1089 * Note that path expressions have a syntax and sometimes require quoting 1090 * (see {@link ConfigUtil#joinPath} and {@link ConfigUtil#splitPath}). 1091 * 1092 * @param path 1093 * path expression for the value's new location 1094 * @param value 1095 * value at the new path 1096 * @return the new instance with the new map entry 1097 */ 1098 Config withValue(String path, ConfigValue value); 1099}