001/** 002 * Copyright (C) 2011-2012 Typesafe Inc. <http://typesafe.com> 003 */ 004package com.typesafe.config; 005 006import com.typesafe.config.impl.ConfigImpl; 007import com.typesafe.config.impl.Parseable; 008 009import java.io.File; 010import java.io.Reader; 011import java.lang.reflect.InvocationTargetException; 012import java.net.MalformedURLException; 013import java.net.URL; 014import java.util.Map; 015import java.util.Optional; 016import java.util.Properties; 017import java.util.concurrent.Callable; 018 019/** 020 * Contains static methods for creating {@link Config} instances. 021 * 022 * <p> 023 * See also {@link ConfigValueFactory} which contains static methods for 024 * converting Java values into a {@link ConfigObject}. You can then convert a 025 * {@code ConfigObject} into a {@code Config} with {@link ConfigObject#toConfig}. 026 * 027 * <p> 028 * The static methods with "load" in the name do some sort of higher-level 029 * operation potentially parsing multiple resources and resolving substitutions, 030 * while the ones with "parse" in the name just create a {@link ConfigValue} 031 * from a resource and nothing else. 032 * 033 * <p> You can find an example app and library <a 034 * href="https://github.com/lightbend/config/tree/main/examples">on 035 * GitHub</a>. Also be sure to read the <a 036 * href="package-summary.html#package_description">package 037 * overview</a> which describes the big picture as shown in those 038 * examples. 039 */ 040public final class ConfigFactory { 041 private static final String STRATEGY_PROPERTY_NAME = "config.strategy"; 042 private static final String OVERRIDE_WITH_ENV_PROPERTY_NAME = "config.override_with_env_vars"; 043 044 private ConfigFactory() { 045 } 046 047 /** 048 * Loads an application's configuration from the given classpath resource or 049 * classpath resource basename, sandwiches it between default reference 050 * config and default overrides, and then resolves it. The classpath 051 * resource is "raw" (it should have no "/" prefix, and is not made relative 052 * to any package, so it's like {@link ClassLoader#getResource} not 053 * {@link Class#getResource}). 054 * 055 * <p> 056 * Resources are loaded from the current thread's 057 * {@link Thread#getContextClassLoader()}. In general, a library needs its 058 * configuration to come from the class loader used to load that library, so 059 * the proper "reference.conf" are present. 060 * 061 * <p> 062 * The loaded object will already be resolved (substitutions have already 063 * been processed). As a result, if you add more fallbacks then they won't 064 * be seen by substitutions. Substitutions are the "${foo.bar}" syntax. If 065 * you want to parse additional files or something then you need to use 066 * {@link #load(Config)}. 067 * 068 * <p> 069 * To load a standalone resource (without the default reference and default 070 * overrides), use {@link #parseResourcesAnySyntax(String)} rather than this 071 * method. To load only the reference config use {@link #defaultReference()} 072 * and to load only the overrides use {@link #defaultOverrides()}. 073 * 074 * @param resourceBasename 075 * name (optionally without extension) of a resource on classpath 076 * @return configuration for an application relative to context class loader 077 */ 078 public static Config load(String resourceBasename) { 079 return load(resourceBasename, ConfigParseOptions.defaults(), 080 ConfigResolveOptions.defaults()); 081 } 082 083 /** 084 * Like {@link #load(String)} but uses the supplied class loader instead of 085 * the current thread's context class loader. 086 * 087 * <p> 088 * To load a standalone resource (without the default reference and default 089 * overrides), use {@link #parseResourcesAnySyntax(ClassLoader, String)} 090 * rather than this method. To load only the reference config use 091 * {@link #defaultReference(ClassLoader)} and to load only the overrides use 092 * {@link #defaultOverrides(ClassLoader)}. 093 * 094 * @param loader class loader to look for resources in 095 * @param resourceBasename basename (no .conf/.json/.properties suffix) 096 * @return configuration for an application relative to given class loader 097 */ 098 public static Config load(ClassLoader loader, String resourceBasename) { 099 return load(resourceBasename, ConfigParseOptions.defaults().setClassLoader(loader), 100 ConfigResolveOptions.defaults()); 101 } 102 103 /** 104 * Like {@link #load(String)} but allows you to specify parse and resolve 105 * options. 106 * 107 * @param resourceBasename 108 * the classpath resource name with optional extension 109 * @param parseOptions 110 * options to use when parsing the resource 111 * @param resolveOptions 112 * options to use when resolving the stack 113 * @return configuration for an application 114 */ 115 public static Config load(String resourceBasename, ConfigParseOptions parseOptions, 116 ConfigResolveOptions resolveOptions) { 117 ConfigParseOptions withLoader = ensureClassLoader(parseOptions, "load"); 118 Config appConfig = ConfigFactory.parseResourcesAnySyntax(resourceBasename, withLoader); 119 return load(withLoader.getClassLoader(), appConfig, resolveOptions); 120 } 121 122 /** 123 * Like {@link #load(String,ConfigParseOptions,ConfigResolveOptions)} but 124 * has a class loader parameter that overrides any from the 125 * {@code ConfigParseOptions}. 126 * 127 * @param loader 128 * class loader in which to find resources (overrides loader in 129 * parse options) 130 * @param resourceBasename 131 * the classpath resource name with optional extension 132 * @param parseOptions 133 * options to use when parsing the resource (class loader 134 * overridden) 135 * @param resolveOptions 136 * options to use when resolving the stack 137 * @return configuration for an application 138 */ 139 public static Config load(ClassLoader loader, String resourceBasename, 140 ConfigParseOptions parseOptions, ConfigResolveOptions resolveOptions) { 141 return load(resourceBasename, parseOptions.setClassLoader(loader), resolveOptions); 142 } 143 144 private static ClassLoader checkedContextClassLoader(String methodName) { 145 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 146 if (loader == null) 147 throw new ConfigException.BugOrBroken("Context class loader is not set for the current thread; " 148 + "if Thread.currentThread().getContextClassLoader() returns null, you must pass a ClassLoader " 149 + "explicitly to ConfigFactory." + methodName); 150 else 151 return loader; 152 } 153 154 private static ConfigParseOptions ensureClassLoader(ConfigParseOptions options, String methodName) { 155 if (options.getClassLoader() == null) 156 return options.setClassLoader(checkedContextClassLoader(methodName)); 157 else 158 return options; 159 } 160 161 /** 162 * Assembles a standard configuration using a custom <code>Config</code> 163 * object rather than loading "application.conf". The <code>Config</code> 164 * object will be sandwiched between the default reference config and 165 * default overrides and then resolved. 166 * 167 * @param config 168 * the application's portion of the configuration 169 * @return resolved configuration with overrides and fallbacks added 170 */ 171 public static Config load(Config config) { 172 return load(checkedContextClassLoader("load"), config); 173 } 174 175 /** 176 * Like {@link #load(Config)} but allows you to specify 177 * the class loader for looking up resources. 178 * 179 * @param loader 180 * the class loader to use to find resources 181 * @param config 182 * the application's portion of the configuration 183 * @return resolved configuration with overrides and fallbacks added 184 */ 185 public static Config load(ClassLoader loader, Config config) { 186 return load(loader, config, ConfigResolveOptions.defaults()); 187 } 188 189 /** 190 * Like {@link #load(Config)} but allows you to specify 191 * {@link ConfigResolveOptions}. 192 * 193 * @param config 194 * the application's portion of the configuration 195 * @param resolveOptions 196 * options for resolving the assembled config stack 197 * @return resolved configuration with overrides and fallbacks added 198 */ 199 public static Config load(Config config, ConfigResolveOptions resolveOptions) { 200 return load(checkedContextClassLoader("load"), config, resolveOptions); 201 } 202 203 /** 204 * Like {@link #load(Config,ConfigResolveOptions)} but allows you to specify 205 * a class loader other than the context class loader. 206 * 207 * @param loader 208 * class loader to use when looking up override and reference 209 * configs 210 * @param config 211 * the application's portion of the configuration 212 * @param resolveOptions 213 * options for resolving the assembled config stack 214 * @return resolved configuration with overrides and fallbacks added 215 */ 216 public static Config load(ClassLoader loader, Config config, ConfigResolveOptions resolveOptions) { 217 return defaultOverrides(loader).withFallback(config) 218 .withFallback(ConfigImpl.defaultReferenceUnresolved(loader)) 219 .resolve(resolveOptions); 220 } 221 222 223 224 /** 225 * Loads a default configuration, equivalent to {@link #load(Config) 226 * load(defaultApplication())} in most cases. This configuration should be used by 227 * libraries and frameworks unless an application provides a different one. 228 * <p> 229 * This method may return a cached singleton so will not see changes to 230 * system properties or config files. (Use {@link #invalidateCaches()} to 231 * force it to reload.) 232 * 233 * @return configuration for an application 234 */ 235 public static Config load() { 236 ClassLoader loader = checkedContextClassLoader("load"); 237 return load(loader); 238 } 239 240 /** 241 * Like {@link #load()} but allows specifying parse options. 242 * 243 * @param parseOptions 244 * Options for parsing resources 245 * @return configuration for an application 246 */ 247 public static Config load(ConfigParseOptions parseOptions) { 248 return load(parseOptions, ConfigResolveOptions.defaults()); 249 } 250 251 /** 252 * Like {@link #load()} but allows specifying a class loader other than the 253 * thread's current context class loader. 254 * 255 * @param loader 256 * class loader for finding resources 257 * @return configuration for an application 258 */ 259 public static Config load(final ClassLoader loader) { 260 final ConfigParseOptions withLoader = ConfigParseOptions.defaults().setClassLoader(loader); 261 return ConfigImpl.computeCachedConfig(loader, "load", new Callable<Config>() { 262 @Override 263 public Config call() { 264 return load(loader, defaultApplication(withLoader)); 265 } 266 }); 267 } 268 269 /** 270 * Like {@link #load()} but allows specifying a class loader other than the 271 * thread's current context class loader and also specify parse options. 272 * 273 * @param loader 274 * class loader for finding resources (overrides any loader in parseOptions) 275 * @param parseOptions 276 * Options for parsing resources 277 * @return configuration for an application 278 */ 279 public static Config load(ClassLoader loader, ConfigParseOptions parseOptions) { 280 return load(parseOptions.setClassLoader(loader)); 281 } 282 283 /** 284 * Like {@link #load()} but allows specifying a class loader other than the 285 * thread's current context class loader and also specify resolve options. 286 * 287 * @param loader 288 * class loader for finding resources 289 * @param resolveOptions 290 * options for resolving the assembled config stack 291 * @return configuration for an application 292 */ 293 public static Config load(ClassLoader loader, ConfigResolveOptions resolveOptions) { 294 return load(loader, ConfigParseOptions.defaults(), resolveOptions); 295 } 296 297 298 /** 299 * Like {@link #load()} but allows specifying a class loader other than the 300 * thread's current context class loader, parse options, and resolve options. 301 * 302 * @param loader 303 * class loader for finding resources (overrides any loader in parseOptions) 304 * @param parseOptions 305 * Options for parsing resources 306 * @param resolveOptions 307 * options for resolving the assembled config stack 308 * @return configuration for an application 309 */ 310 public static Config load(ClassLoader loader, ConfigParseOptions parseOptions, ConfigResolveOptions resolveOptions) { 311 final ConfigParseOptions withLoader = ensureClassLoader(parseOptions, "load"); 312 return load(loader, defaultApplication(withLoader), resolveOptions); 313 } 314 315 /** 316 * Like {@link #load()} but allows specifying parse options and resolve 317 * options. 318 * 319 * @param parseOptions 320 * Options for parsing resources 321 * @param resolveOptions 322 * options for resolving the assembled config stack 323 * @return configuration for an application 324 * 325 * @since 1.3.0 326 */ 327 public static Config load(ConfigParseOptions parseOptions, final ConfigResolveOptions resolveOptions) { 328 final ConfigParseOptions withLoader = ensureClassLoader(parseOptions, "load"); 329 return load(defaultApplication(withLoader), resolveOptions); 330 } 331 332 /** 333 * Obtains the default reference configuration, which is currently created 334 * by merging all resources "reference.conf" found on the classpath and 335 * overriding the result with system properties. The returned reference 336 * configuration will already have substitutions resolved. 337 * 338 * <p> 339 * Libraries and frameworks should ship with a "reference.conf" in their 340 * jar. 341 * 342 * <p> 343 * The reference config must be looked up in the class loader that contains 344 * the libraries that you want to use with this config, so the 345 * "reference.conf" for each library can be found. Use 346 * {@link #defaultReference(ClassLoader)} if the context class loader is not 347 * suitable. 348 * 349 * <p> 350 * The {@link #load()} methods merge this configuration for you 351 * automatically. 352 * 353 * <p> 354 * Future versions may look for reference configuration in more places. It 355 * is not guaranteed that this method <em>only</em> looks at 356 * "reference.conf". 357 * 358 * @return the default reference config for context class loader 359 */ 360 public static Config defaultReference() { 361 return defaultReference(checkedContextClassLoader("defaultReference")); 362 } 363 364 /** 365 * Like {@link #defaultReference()} but allows you to specify a class loader 366 * to use rather than the current context class loader. 367 * 368 * @param loader class loader to look for resources in 369 * @return the default reference config for this class loader 370 */ 371 public static Config defaultReference(ClassLoader loader) { 372 return ConfigImpl.defaultReference(loader); 373 } 374 375 /** 376 * Obtains the default reference configuration, which is currently created 377 * by merging all resources "reference.conf" found on the classpath and 378 * overriding the result with system properties. 379 * 380 * <p> 381 * While the returned reference configuration is guaranteed to be 382 * resolvable (that is, there will be no substitutions that cannot be 383 * resolved), it is returned in an unresolved state for the purpose of 384 * allowing substitutions to be overridden by a config layer that falls 385 * back to this one. 386 * 387 * <p> 388 * Libraries and frameworks should ship with a "reference.conf" in their 389 * jar. 390 * 391 * <p> 392 * The reference config must be looked up in the class loader that contains 393 * the libraries that you want to use with this config, so the 394 * "reference.conf" for each library can be found. Use 395 * {@link #defaultReference(ClassLoader)} if the context class loader is not 396 * suitable. 397 * 398 * <p> 399 * The {@link #load()} methods merge this configuration for you 400 * automatically. 401 * 402 * <p> 403 * Future versions may look for reference configuration in more places. It 404 * is not guaranteed that this method <em>only</em> looks at 405 * "reference.conf". 406 * 407 * @return the unresolved default reference config for the context class 408 * loader 409 */ 410 public static Config defaultReferenceUnresolved() { 411 return defaultReferenceUnresolved(checkedContextClassLoader("defaultReferenceUnresolved")); 412 } 413 414 /** 415 * Like {@link #defaultReferenceUnresolved()} but allows you to specify a 416 * class loader to use rather than the current context class loader. 417 * 418 * @param loader class loader to look for resources in 419 * @return the unresolved default reference config for this class loader 420 */ 421 public static Config defaultReferenceUnresolved(ClassLoader loader) { 422 return ConfigImpl.defaultReferenceUnresolved(loader); 423 } 424 425 /** 426 * Obtains the default override configuration, which currently consists of 427 * system properties. The returned override configuration will already have 428 * substitutions resolved. 429 * 430 * <p> 431 * The {@link #load()} methods merge this configuration for you 432 * automatically. 433 * 434 * <p> 435 * Future versions may get overrides in more places. It is not guaranteed 436 * that this method <em>only</em> uses system properties. 437 * 438 * @return the default override configuration 439 */ 440 public static Config defaultOverrides() { 441 if (getOverrideWithEnv()) { 442 return systemEnvironmentOverrides().withFallback(systemProperties()); 443 } else { 444 return systemProperties(); 445 } 446 } 447 448 /** 449 * Like {@link #defaultOverrides()} but allows you to specify a class loader 450 * to use rather than the current context class loader. 451 * 452 * @param loader class loader to look for resources in 453 * @return the default override configuration 454 */ 455 public static Config defaultOverrides(ClassLoader loader) { 456 return defaultOverrides(); 457 } 458 459 /** 460 * Obtains the default application-specific configuration, 461 * which defaults to parsing <code>application.conf</code>, 462 * <code>application.json</code>, and 463 * <code>application.properties</code> on the classpath, but 464 * can also be rerouted using the <code>config.file</code>, 465 * <code>config.resource</code>, and <code>config.url</code> 466 * system properties. 467 * 468 * <p> The no-arguments {@link #load()} method automatically 469 * stacks the {@link #defaultReference()}, {@link 470 * #defaultApplication()}, and {@link #defaultOverrides()} 471 * configs. You would use <code>defaultApplication()</code> 472 * directly only if you're somehow customizing behavior by 473 * reimplementing <code>load()</code>. 474 * 475 * <p>The configuration returned by 476 * <code>defaultApplication()</code> will not be resolved 477 * already, in contrast to <code>defaultReference()</code> and 478 * <code>defaultOverrides()</code>. This is because 479 * application.conf would normally be resolved <em>after</em> 480 * merging with the reference and override configs. 481 * 482 * <p> 483 * If the system properties <code>config.resource</code>, 484 * <code>config.file</code>, or <code>config.url</code> are set, then the 485 * classpath resource, file, or URL specified in those properties will be 486 * used rather than the default 487 * <code>application.{conf,json,properties}</code> classpath resources. 488 * These system properties should not be set in code (after all, you can 489 * just parse whatever you want manually and then use {@link #load(Config)} 490 * if you don't want to use <code>application.conf</code>). The properties 491 * are intended for use by the person or script launching the application. 492 * For example someone might have a <code>production.conf</code> that 493 * include <code>application.conf</code> but then change a couple of values. 494 * When launching the app they could specify 495 * <code>-Dconfig.resource=production.conf</code> to get production mode. 496 * 497 * <p> 498 * If no system properties are set to change the location of the default 499 * configuration, <code>defaultApplication()</code> is equivalent to 500 * <code>ConfigFactory.parseResources("application")</code>. 501 * 502 * @since 1.3.0 503 * 504 * @return the default application.conf or system-property-configured configuration 505 */ 506 public static Config defaultApplication() { 507 return defaultApplication(ConfigParseOptions.defaults()); 508 } 509 510 /** 511 * Like {@link #defaultApplication()} but allows you to specify a class loader 512 * to use rather than the current context class loader. 513 * 514 * @since 1.3.0 515 * 516 * @param loader class loader to look for resources in 517 * @return the default application configuration 518 */ 519 public static Config defaultApplication(ClassLoader loader) { 520 return defaultApplication(ConfigParseOptions.defaults().setClassLoader(loader)); 521 } 522 523 /** 524 * Like {@link #defaultApplication()} but allows you to specify parse options. 525 * 526 * @since 1.3.0 527 * 528 * @param options the options 529 * @return the default application configuration 530 */ 531 public static Config defaultApplication(ConfigParseOptions options) { 532 return getConfigLoadingStrategy().parseApplicationConfig(ensureClassLoader(options, "defaultApplication")); 533 } 534 535 /** 536 * Reloads any cached configs, picking up changes to system properties for 537 * example. Because a {@link Config} is immutable, anyone with a reference 538 * to the old configs will still have the same outdated objects. However, 539 * new calls to {@link #load()} or {@link #defaultOverrides()} or 540 * {@link #defaultReference} may return a new object. 541 * <p> 542 * This method is primarily intended for use in unit tests, for example, 543 * that may want to update a system property then confirm that it's used 544 * correctly. In many cases, use of this method may indicate there's a 545 * better way to set up your code. 546 * <p> 547 * Caches may be reloaded immediately or lazily; once you call this method, 548 * the reload can occur at any time, even during the invalidation process. 549 * So FIRST make the changes you'd like the caches to notice, then SECOND 550 * call this method to invalidate caches. Don't expect that invalidating, 551 * making changes, then calling {@link #load()}, will work. Make changes 552 * before you invalidate. 553 */ 554 public static void invalidateCaches() { 555 // We rely on this having the side effect that it drops 556 // all caches 557 ConfigImpl.reloadSystemPropertiesConfig(); 558 ConfigImpl.reloadEnvVariablesConfig(); 559 ConfigImpl.reloadEnvVariablesOverridesConfig(); 560 } 561 562 /** 563 * Gets an empty configuration. See also {@link #empty(String)} to create an 564 * empty configuration with a description, which may improve user-visible 565 * error messages. 566 * 567 * @return an empty configuration 568 */ 569 public static Config empty() { 570 return empty(null); 571 } 572 573 /** 574 * Gets an empty configuration with a description to be used to create a 575 * {@link ConfigOrigin} for this <code>Config</code>. The description should 576 * be very short and say what the configuration is, like "default settings" 577 * or "foo settings" or something. (Presumably you will merge some actual 578 * settings into this empty config using {@link Config#withFallback}, making 579 * the description more useful.) 580 * 581 * @param originDescription 582 * description of the config 583 * @return an empty configuration 584 */ 585 public static Config empty(String originDescription) { 586 return ConfigImpl.emptyConfig(originDescription); 587 } 588 589 /** 590 * Gets a <code>Config</code> containing the system properties from 591 * {@link java.lang.System#getProperties()}, parsed and converted as with 592 * {@link #parseProperties}. 593 * <p> 594 * This method can return a global immutable singleton, so it's preferred 595 * over parsing system properties yourself. 596 * <p> 597 * {@link #load} will include the system properties as overrides already, as 598 * will {@link #defaultReference} and {@link #defaultOverrides}. 599 * 600 * <p> 601 * Because this returns a singleton, it will not notice changes to system 602 * properties made after the first time this method is called. Use 603 * {@link #invalidateCaches()} to force the singleton to reload if you 604 * modify system properties. 605 * 606 * @return system properties parsed into a <code>Config</code> 607 */ 608 public static Config systemProperties() { 609 return ConfigImpl.systemPropertiesAsConfig(); 610 } 611 612 /** 613 * Gets a <code>Config</code> containing the system's environment variables 614 * used to override configuration keys. 615 * Environment variables taken in considerations are starting with 616 * {@code CONFIG_FORCE_} 617 * 618 * <p> 619 * Environment variables are mangled in the following way after stripping the prefix "CONFIG_FORCE_": 620 * <table border="1"> 621 * <caption>environment variables</caption> 622 * <tr> 623 * <th>Env Var</th> 624 * <th>Config</th> 625 * </tr> 626 * <tr> 627 * <td>_ [1 underscore]</td> 628 * <td>. [dot]</td> 629 * </tr> 630 * <tr> 631 * <td>__ [2 underscore]</td> 632 * <td>- [dash]</td> 633 * </tr> 634 * <tr> 635 * <td>___ [3 underscore]</td> 636 * <td>_ [underscore]</td> 637 * </tr> 638 * </table> 639 * 640 * <p> 641 * A variable like: {@code CONFIG_FORCE_a_b__c___d} 642 * is translated to a config key: {@code a.b-c_d} 643 * 644 * <p> 645 * This method can return a global immutable singleton, so it's preferred 646 * over parsing system properties yourself. 647 * <p> 648 * {@link #defaultOverrides} will include the system environment variables as 649 * overrides if `config.override_with_env_vars` is set to `true`. 650 * 651 * @return system environment variable overrides parsed into a <code>Config</code> 652 */ 653 public static Config systemEnvironmentOverrides() { 654 return ConfigImpl.envVariablesOverridesAsConfig(); 655 } 656 657 /** 658 * Gets a <code>Config</code> containing the system's environment variables. 659 * This method can return a global immutable singleton. 660 * 661 * <p> 662 * Environment variables are used as fallbacks when resolving substitutions 663 * whether or not this object is included in the config being resolved, so 664 * you probably don't need to use this method for most purposes. It can be a 665 * nicer API for accessing environment variables than raw 666 * {@link java.lang.System#getenv(String)} though, since you can use methods 667 * such as {@link Config#getInt}. 668 * 669 * @return system environment variables parsed into a <code>Config</code> 670 */ 671 public static Config systemEnvironment() { 672 return ConfigImpl.envVariablesAsConfig(); 673 } 674 675 /** 676 * Converts a Java {@link java.util.Properties} object to a 677 * {@link ConfigObject} using the rules documented in the <a 678 * href="https://github.com/lightbend/config/blob/main/HOCON.md">HOCON 679 * spec</a>. The keys in the <code>Properties</code> object are split on the 680 * period character '.' and treated as paths. The values will all end up as 681 * string values. If you have both "a=foo" and "a.b=bar" in your properties 682 * file, so "a" is both the object containing "b" and the string "foo", then 683 * the string value is dropped. 684 * 685 * <p> 686 * If you want to have <code>System.getProperties()</code> as a 687 * ConfigObject, it's better to use the {@link #systemProperties()} method 688 * which returns a cached global singleton. 689 * 690 * @param properties 691 * a Java Properties object 692 * @param options 693 * the parse options 694 * @return the parsed configuration 695 */ 696 public static Config parseProperties(Properties properties, 697 ConfigParseOptions options) { 698 return Parseable.newProperties(properties, options).parse().toConfig(); 699 } 700 701 /** 702 * Like {@link #parseProperties(Properties, ConfigParseOptions)} but uses default 703 * parse options. 704 * @param properties 705 * a Java Properties object 706 * @return the parsed configuration 707 */ 708 public static Config parseProperties(Properties properties) { 709 return parseProperties(properties, ConfigParseOptions.defaults()); 710 } 711 712 /** 713 * Parses a Reader into a Config instance. Does not call 714 * {@link Config#resolve} or merge the parsed stream with any 715 * other configuration; this method parses a single stream and 716 * does nothing else. It does process "include" statements in 717 * the parsed stream, and may end up doing other IO due to those 718 * statements. 719 * 720 * @param reader 721 * the reader to parse 722 * @param options 723 * parse options to control how the reader is interpreted 724 * @return the parsed configuration 725 * @throws ConfigException on IO or parse errors 726 */ 727 public static Config parseReader(Reader reader, ConfigParseOptions options) { 728 return Parseable.newReader(reader, options).parse().toConfig(); 729 } 730 731 /** 732 * Parses a reader into a Config instance as with 733 * {@link #parseReader(Reader,ConfigParseOptions)} but always uses the 734 * default parse options. 735 * 736 * @param reader 737 * the reader to parse 738 * @return the parsed configuration 739 * @throws ConfigException on IO or parse errors 740 */ 741 public static Config parseReader(Reader reader) { 742 return parseReader(reader, ConfigParseOptions.defaults()); 743 } 744 745 /** 746 * Parses a URL into a Config instance. Does not call 747 * {@link Config#resolve} or merge the parsed stream with any 748 * other configuration; this method parses a single stream and 749 * does nothing else. It does process "include" statements in 750 * the parsed stream, and may end up doing other IO due to those 751 * statements. 752 * 753 * @param url 754 * the url to parse 755 * @param options 756 * parse options to control how the url is interpreted 757 * @return the parsed configuration 758 * @throws ConfigException on IO or parse errors 759 */ 760 public static Config parseURL(URL url, ConfigParseOptions options) { 761 return Parseable.newURL(url, options).parse().toConfig(); 762 } 763 764 /** 765 * Parses a url into a Config instance as with 766 * {@link #parseURL(URL,ConfigParseOptions)} but always uses the 767 * default parse options. 768 * 769 * @param url 770 * the url to parse 771 * @return the parsed configuration 772 * @throws ConfigException on IO or parse errors 773 */ 774 public static Config parseURL(URL url) { 775 return parseURL(url, ConfigParseOptions.defaults()); 776 } 777 778 /** 779 * Parses a file into a Config instance. Does not call 780 * {@link Config#resolve} or merge the file with any other 781 * configuration; this method parses a single file and does 782 * nothing else. It does process "include" statements in the 783 * parsed file, and may end up doing other IO due to those 784 * statements. 785 * 786 * @param file 787 * the file to parse 788 * @param options 789 * parse options to control how the file is interpreted 790 * @return the parsed configuration 791 * @throws ConfigException on IO or parse errors 792 */ 793 public static Config parseFile(File file, ConfigParseOptions options) { 794 return Parseable.newFile(file, options).parse().toConfig(); 795 } 796 797 /** 798 * Parses a file into a Config instance as with 799 * {@link #parseFile(File,ConfigParseOptions)} but always uses the 800 * default parse options. 801 * 802 * @param file 803 * the file to parse 804 * @return the parsed configuration 805 * @throws ConfigException on IO or parse errors 806 */ 807 public static Config parseFile(File file) { 808 return parseFile(file, ConfigParseOptions.defaults()); 809 } 810 811 /** 812 * Parses a file with a flexible extension. If the <code>fileBasename</code> 813 * already ends in a known extension, this method parses it according to 814 * that extension (the file's syntax must match its extension). If the 815 * <code>fileBasename</code> does not end in an extension, it parses files 816 * with all known extensions and merges whatever is found. 817 * 818 * <p> 819 * In the current implementation, the extension ".conf" forces 820 * {@link ConfigSyntax#CONF}, ".json" forces {@link ConfigSyntax#JSON}, and 821 * ".properties" forces {@link ConfigSyntax#PROPERTIES}. When merging files, 822 * ".conf" falls back to ".json" falls back to ".properties". 823 * 824 * <p> 825 * Future versions of the implementation may add additional syntaxes or 826 * additional extensions. However, the ordering (fallback priority) of the 827 * three current extensions will remain the same. 828 * 829 * <p> 830 * If <code>options</code> forces a specific syntax, this method only parses 831 * files with an extension matching that syntax. 832 * 833 * <p> 834 * If {@link ConfigParseOptions#getAllowMissing options.getAllowMissing()} 835 * is true, then no files have to exist; if false, then at least one file 836 * has to exist. 837 * 838 * @param fileBasename 839 * a filename with or without extension 840 * @param options 841 * parse options 842 * @return the parsed configuration 843 */ 844 public static Config parseFileAnySyntax(File fileBasename, 845 ConfigParseOptions options) { 846 return ConfigImpl.parseFileAnySyntax(fileBasename, options).toConfig(); 847 } 848 849 /** 850 * Like {@link #parseFileAnySyntax(File,ConfigParseOptions)} but always uses 851 * default parse options. 852 * 853 * @param fileBasename 854 * a filename with or without extension 855 * @return the parsed configuration 856 */ 857 public static Config parseFileAnySyntax(File fileBasename) { 858 return parseFileAnySyntax(fileBasename, ConfigParseOptions.defaults()); 859 } 860 861 /** 862 * Parses all resources on the classpath with the given name and merges them 863 * into a single <code>Config</code>. 864 * 865 * <p> 866 * If the resource name does not begin with a "/", it will have the supplied 867 * class's package added to it, in the same way as 868 * {@link java.lang.Class#getResource}. 869 * 870 * <p> 871 * Duplicate resources with the same name are merged such that ones returned 872 * earlier from {@link ClassLoader#getResources} fall back to (have higher 873 * priority than) the ones returned later. This implies that resources 874 * earlier in the classpath override those later in the classpath when they 875 * configure the same setting. However, in practice real applications may 876 * not be consistent about classpath ordering, so be careful. It may be best 877 * to avoid assuming too much. 878 * 879 * @param klass 880 * <code>klass.getClassLoader()</code> will be used to load 881 * resources, and non-absolute resource names will have this 882 * class's package added 883 * @param resource 884 * resource to look up, relative to <code>klass</code>'s package 885 * or absolute starting with a "/" 886 * @param options 887 * parse options 888 * @return the parsed configuration 889 */ 890 public static Config parseResources(Class<?> klass, String resource, 891 ConfigParseOptions options) { 892 return Parseable.newResources(klass, resource, options).parse() 893 .toConfig(); 894 } 895 896 /** 897 * Like {@link #parseResources(Class,String,ConfigParseOptions)} but always uses 898 * default parse options. 899 * 900 * @param klass 901 * <code>klass.getClassLoader()</code> will be used to load 902 * resources, and non-absolute resource names will have this 903 * class's package added 904 * @param resource 905 * resource to look up, relative to <code>klass</code>'s package 906 * or absolute starting with a "/" 907 * @return the parsed configuration 908 */ 909 public static Config parseResources(Class<?> klass, String resource) { 910 return parseResources(klass, resource, ConfigParseOptions.defaults()); 911 } 912 913 /** 914 * Parses classpath resources with a flexible extension. In general, this 915 * method has the same behavior as 916 * {@link #parseFileAnySyntax(File,ConfigParseOptions)} but for classpath 917 * resources instead, as in {@link #parseResources}. 918 * 919 * <p> 920 * There is a thorny problem with this method, which is that 921 * {@link java.lang.ClassLoader#getResources} must be called separately for 922 * each possible extension. The implementation ends up with separate lists 923 * of resources called "basename.conf" and "basename.json" for example. As a 924 * result, the ideal ordering between two files with different extensions is 925 * unknown; there is no way to figure out how to merge the two lists in 926 * classpath order. To keep it simple, the lists are simply concatenated, 927 * with the same syntax priorities as 928 * {@link #parseFileAnySyntax(File,ConfigParseOptions) parseFileAnySyntax()} 929 * - all ".conf" resources are ahead of all ".json" resources which are 930 * ahead of all ".properties" resources. 931 * 932 * @param klass 933 * class which determines the <code>ClassLoader</code> and the 934 * package for relative resource names 935 * @param resourceBasename 936 * a resource name as in {@link java.lang.Class#getResource}, 937 * with or without extension 938 * @param options 939 * parse options (class loader is ignored in favor of the one 940 * from klass) 941 * @return the parsed configuration 942 */ 943 public static Config parseResourcesAnySyntax(Class<?> klass, String resourceBasename, 944 ConfigParseOptions options) { 945 return ConfigImpl.parseResourcesAnySyntax(klass, resourceBasename, 946 options).toConfig(); 947 } 948 949 /** 950 * Like {@link #parseResourcesAnySyntax(Class,String,ConfigParseOptions)} 951 * but always uses default parse options. 952 * 953 * @param klass 954 * <code>klass.getClassLoader()</code> will be used to load 955 * resources, and non-absolute resource names will have this 956 * class's package added 957 * @param resourceBasename 958 * a resource name as in {@link java.lang.Class#getResource}, 959 * with or without extension 960 * @return the parsed configuration 961 */ 962 public static Config parseResourcesAnySyntax(Class<?> klass, String resourceBasename) { 963 return parseResourcesAnySyntax(klass, resourceBasename, ConfigParseOptions.defaults()); 964 } 965 966 /** 967 * Parses all resources on the classpath with the given name and merges them 968 * into a single <code>Config</code>. 969 * 970 * <p> 971 * This works like {@link java.lang.ClassLoader#getResource}, not like 972 * {@link java.lang.Class#getResource}, so the name never begins with a 973 * slash. 974 * 975 * <p> 976 * See {@link #parseResources(Class,String,ConfigParseOptions)} for full 977 * details. 978 * 979 * @param loader 980 * will be used to load resources by setting this loader on the 981 * provided options 982 * @param resource 983 * resource to look up 984 * @param options 985 * parse options (class loader is ignored) 986 * @return the parsed configuration 987 */ 988 public static Config parseResources(ClassLoader loader, String resource, 989 ConfigParseOptions options) { 990 return parseResources(resource, options.setClassLoader(loader)); 991 } 992 993 /** 994 * Like {@link #parseResources(ClassLoader,String,ConfigParseOptions)} but always uses 995 * default parse options. 996 * 997 * @param loader 998 * will be used to load resources 999 * @param resource 1000 * resource to look up in the loader 1001 * @return the parsed configuration 1002 */ 1003 public static Config parseResources(ClassLoader loader, String resource) { 1004 return parseResources(loader, resource, ConfigParseOptions.defaults()); 1005 } 1006 1007 /** 1008 * Parses classpath resources with a flexible extension. In general, this 1009 * method has the same behavior as 1010 * {@link #parseFileAnySyntax(File,ConfigParseOptions)} but for classpath 1011 * resources instead, as in 1012 * {@link #parseResources(ClassLoader,String,ConfigParseOptions)}. 1013 * 1014 * <p> 1015 * {@link #parseResourcesAnySyntax(Class,String,ConfigParseOptions)} differs 1016 * in the syntax for the resource name, but otherwise see 1017 * {@link #parseResourcesAnySyntax(Class,String,ConfigParseOptions)} for 1018 * some details and caveats on this method. 1019 * 1020 * @param loader 1021 * class loader to look up resources in, will be set on options 1022 * @param resourceBasename 1023 * a resource name as in 1024 * {@link java.lang.ClassLoader#getResource}, with or without 1025 * extension 1026 * @param options 1027 * parse options (class loader ignored) 1028 * @return the parsed configuration 1029 */ 1030 public static Config parseResourcesAnySyntax(ClassLoader loader, String resourceBasename, 1031 ConfigParseOptions options) { 1032 return ConfigImpl.parseResourcesAnySyntax(resourceBasename, options.setClassLoader(loader)) 1033 .toConfig(); 1034 } 1035 1036 /** 1037 * Like {@link #parseResourcesAnySyntax(ClassLoader,String,ConfigParseOptions)} but always uses 1038 * default parse options. 1039 * 1040 * @param loader 1041 * will be used to load resources 1042 * @param resourceBasename 1043 * a resource name as in 1044 * {@link java.lang.ClassLoader#getResource}, with or without 1045 * extension 1046 * @return the parsed configuration 1047 */ 1048 public static Config parseResourcesAnySyntax(ClassLoader loader, String resourceBasename) { 1049 return parseResourcesAnySyntax(loader, resourceBasename, ConfigParseOptions.defaults()); 1050 } 1051 1052 /** 1053 * Like {@link #parseResources(ClassLoader,String,ConfigParseOptions)} but 1054 * uses thread's current context class loader if none is set in the 1055 * ConfigParseOptions. 1056 * @param resource the resource name 1057 * @param options parse options 1058 * @return the parsed configuration 1059 */ 1060 public static Config parseResources(String resource, ConfigParseOptions options) { 1061 ConfigParseOptions withLoader = ensureClassLoader(options, "parseResources"); 1062 return Parseable.newResources(resource, withLoader).parse().toConfig(); 1063 } 1064 1065 /** 1066 * Like {@link #parseResources(ClassLoader,String)} but uses thread's 1067 * current context class loader. 1068 * @param resource the resource name 1069 * @return the parsed configuration 1070 */ 1071 public static Config parseResources(String resource) { 1072 return parseResources(resource, ConfigParseOptions.defaults()); 1073 } 1074 1075 /** 1076 * Like 1077 * {@link #parseResourcesAnySyntax(ClassLoader,String,ConfigParseOptions)} 1078 * but uses thread's current context class loader. 1079 * @param resourceBasename the resource basename (no file type suffix) 1080 * @param options parse options 1081 * @return the parsed configuration 1082 */ 1083 public static Config parseResourcesAnySyntax(String resourceBasename, ConfigParseOptions options) { 1084 return ConfigImpl.parseResourcesAnySyntax(resourceBasename, options).toConfig(); 1085 } 1086 1087 /** 1088 * Like {@link #parseResourcesAnySyntax(ClassLoader,String)} but uses 1089 * thread's current context class loader. 1090 * @param resourceBasename the resource basename (no file type suffix) 1091 * @return the parsed configuration 1092 */ 1093 public static Config parseResourcesAnySyntax(String resourceBasename) { 1094 return parseResourcesAnySyntax(resourceBasename, ConfigParseOptions.defaults()); 1095 } 1096 1097 /** 1098 * Parse only any application replacement (specified by one of config.{resource,file,url}), returning 1099 * an empty Config if no overrides were set. 1100 * 1101 * @since 1.4.1 1102 * 1103 * @return a {@link java.util.Optional} containing any specified replacement, or {@link Optional#empty()} 1104 * if none was specified. 1105 */ 1106 public static java.util.Optional<Config> parseApplicationReplacement() { 1107 return parseApplicationReplacement(ConfigParseOptions.defaults()); 1108 } 1109 1110 /** 1111 * Like {@link #parseApplicationReplacement()} but allows you to specify a class loader 1112 * ti yse rather than the current context class loader. 1113 * 1114 * @since 1.4.1 1115 * 1116 * @param loader the class loader 1117 * @return a {@link java.util.Optional} containing any specified replacement, or {@link Optional#empty()} 1118 * if none was specified. 1119 */ 1120 public static java.util.Optional<Config> parseApplicationReplacement(ClassLoader loader) { 1121 return parseApplicationReplacement(ConfigParseOptions.defaults().setClassLoader(loader)); 1122 } 1123 1124 /** 1125 * Like {@link #parseApplicationReplacement()} but allows you to specify parse options. 1126 * 1127 * @since 1.4.1 1128 * 1129 * @param parseOptions parse options 1130 * @return a {@link java.util.Optional} containing any specified replacement, or {@link Optional#empty()} 1131 * if none was specified. 1132 */ 1133 public static java.util.Optional<Config> parseApplicationReplacement(ConfigParseOptions parseOptions) { 1134 final ConfigParseOptions withLoader = ensureClassLoader(parseOptions, "parseApplicationReplacement"); 1135 ClassLoader loader = withLoader.getClassLoader(); 1136 1137 int specified = 0; 1138 1139 // override application.conf with config.file, config.resource, 1140 // config.url if requested. 1141 String resource = System.getProperty("config.resource"); 1142 if (resource != null) 1143 specified += 1; 1144 String file = System.getProperty("config.file"); 1145 if (file != null) 1146 specified += 1; 1147 String url = System.getProperty("config.url"); 1148 if (url != null) 1149 specified += 1; 1150 1151 if (specified == 0) { 1152 return java.util.Optional.empty(); 1153 } else if (specified > 1) { 1154 throw new ConfigException.Generic("You set more than one of config.file='" + file 1155 + "', config.url='" + url + "', config.resource='" + resource 1156 + "'; don't know which one to use!"); 1157 } else { 1158 // the override file/url/resource MUST be present or it's an error 1159 ConfigParseOptions overrideOptions = parseOptions.setAllowMissing(false); 1160 if (resource != null) { 1161 if (resource.startsWith("/")) 1162 resource = resource.substring(1); 1163 // this deliberately does not parseResourcesAnySyntax; if 1164 // people want that they can use an include statement. 1165 return java.util.Optional.of(ConfigFactory.parseResources(loader, resource, overrideOptions)); 1166 } else if (file != null) { 1167 return java.util.Optional.of(ConfigFactory.parseFile(new File(file), overrideOptions)); 1168 } else { 1169 try { 1170 return java.util.Optional.of(ConfigFactory.parseURL(new URL(url), overrideOptions)); 1171 } catch (MalformedURLException e) { 1172 throw new ConfigException.Generic("Bad URL in config.url system property: '" 1173 + url + "': " + e.getMessage(), e); 1174 } 1175 } 1176 } 1177 1178 } 1179 1180 /** 1181 * Parses a string (which should be valid HOCON or JSON by default, or 1182 * the syntax specified in the options otherwise). 1183 * 1184 * @param s string to parse 1185 * @param options parse options 1186 * @return the parsed configuration 1187 */ 1188 public static Config parseString(String s, ConfigParseOptions options) { 1189 return Parseable.newString(s, options).parse().toConfig(); 1190 } 1191 1192 /** 1193 * Parses a string (which should be valid HOCON or JSON). 1194 * 1195 * @param s string to parse 1196 * @return the parsed configuration 1197 */ 1198 public static Config parseString(String s) { 1199 return parseString(s, ConfigParseOptions.defaults()); 1200 } 1201 1202 /** 1203 * Creates a {@code Config} based on a {@link java.util.Map} from paths to 1204 * plain Java values. Similar to 1205 * {@link ConfigValueFactory#fromMap(Map,String)}, except the keys in the 1206 * map are path expressions, rather than keys; and correspondingly it 1207 * returns a {@code Config} instead of a {@code ConfigObject}. This is more 1208 * convenient if you are writing literal maps in code, and less convenient 1209 * if you are getting your maps from some data source such as a parser. 1210 * 1211 * <p> 1212 * An exception will be thrown (and it is a bug in the caller of the method) 1213 * if a path is both an object and a value, for example if you had both 1214 * "a=foo" and "a.b=bar", then "a" is both the string "foo" and the parent 1215 * object of "b". The caller of this method should ensure that doesn't 1216 * happen. 1217 * 1218 * @param values map from paths to plain Java objects 1219 * @param originDescription 1220 * description of what this map represents, like a filename, or 1221 * "default settings" (origin description is used in error 1222 * messages) 1223 * @return the map converted to a {@code Config} 1224 */ 1225 public static Config parseMap(Map<String, ? extends Object> values, 1226 String originDescription) { 1227 return ConfigImpl.fromPathMap(values, originDescription).toConfig(); 1228 } 1229 1230 /** 1231 * See the other overload of {@link #parseMap(Map, String)} for details, 1232 * this one just uses a default origin description. 1233 * 1234 * @param values map from paths to plain Java values 1235 * @return the map converted to a {@code Config} 1236 */ 1237 public static Config parseMap(Map<String, ? extends Object> values) { 1238 return parseMap(values, null); 1239 } 1240 1241 private static ConfigLoadingStrategy getConfigLoadingStrategy() { 1242 String className = System.getProperties().getProperty(STRATEGY_PROPERTY_NAME); 1243 1244 if (className != null) { 1245 try { 1246 return Class.forName(className).asSubclass(ConfigLoadingStrategy.class).getDeclaredConstructor().newInstance(); 1247 } catch (InvocationTargetException e) { 1248 Throwable cause = e.getCause(); 1249 if (cause == null) throw new ConfigException.BugOrBroken("Failed to load strategy: " + className, e); 1250 else throw new ConfigException.BugOrBroken("Failed to load strategy: " + className, cause); 1251 } catch (Throwable e) { 1252 throw new ConfigException.BugOrBroken("Failed to load strategy: " + className, e); 1253 } 1254 } else { 1255 return new DefaultConfigLoadingStrategy(); 1256 } 1257 } 1258 1259 private static Boolean getOverrideWithEnv() { 1260 String overrideWithEnv = System.getProperties().getProperty(OVERRIDE_WITH_ENV_PROPERTY_NAME); 1261 1262 return Boolean.parseBoolean(overrideWithEnv); 1263 } 1264}