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 * <tr> 622 * <th bgcolor="silver">Env Var</th> 623 * <th bgcolor="silver">Config</th> 624 * </tr> 625 * <tr> 626 * <td>_ [1 underscore]</td> 627 * <td>. [dot]</td> 628 * </tr> 629 * <tr> 630 * <td>__ [2 underscore]</td> 631 * <td>- [dash]</td> 632 * </tr> 633 * <tr> 634 * <td>___ [3 underscore]</td> 635 * <td>_ [underscore]</td> 636 * </tr> 637 * </table> 638 * 639 * <p> 640 * A variable like: {@code CONFIG_FORCE_a_b__c___d} 641 * is translated to a config key: {@code a.b-c_d} 642 * 643 * <p> 644 * This method can return a global immutable singleton, so it's preferred 645 * over parsing system properties yourself. 646 * <p> 647 * {@link #defaultOverrides} will include the system environment variables as 648 * overrides if `config.override_with_env_vars` is set to `true`. 649 * 650 * @return system environment variable overrides parsed into a <code>Config</code> 651 */ 652 public static Config systemEnvironmentOverrides() { 653 return ConfigImpl.envVariablesOverridesAsConfig(); 654 } 655 656 /** 657 * Gets a <code>Config</code> containing the system's environment variables. 658 * This method can return a global immutable singleton. 659 * 660 * <p> 661 * Environment variables are used as fallbacks when resolving substitutions 662 * whether or not this object is included in the config being resolved, so 663 * you probably don't need to use this method for most purposes. It can be a 664 * nicer API for accessing environment variables than raw 665 * {@link java.lang.System#getenv(String)} though, since you can use methods 666 * such as {@link Config#getInt}. 667 * 668 * @return system environment variables parsed into a <code>Config</code> 669 */ 670 public static Config systemEnvironment() { 671 return ConfigImpl.envVariablesAsConfig(); 672 } 673 674 /** 675 * Converts a Java {@link java.util.Properties} object to a 676 * {@link ConfigObject} using the rules documented in the <a 677 * href="https://github.com/lightbend/config/blob/main/HOCON.md">HOCON 678 * spec</a>. The keys in the <code>Properties</code> object are split on the 679 * period character '.' and treated as paths. The values will all end up as 680 * string values. If you have both "a=foo" and "a.b=bar" in your properties 681 * file, so "a" is both the object containing "b" and the string "foo", then 682 * the string value is dropped. 683 * 684 * <p> 685 * If you want to have <code>System.getProperties()</code> as a 686 * ConfigObject, it's better to use the {@link #systemProperties()} method 687 * which returns a cached global singleton. 688 * 689 * @param properties 690 * a Java Properties object 691 * @param options 692 * the parse options 693 * @return the parsed configuration 694 */ 695 public static Config parseProperties(Properties properties, 696 ConfigParseOptions options) { 697 return Parseable.newProperties(properties, options).parse().toConfig(); 698 } 699 700 /** 701 * Like {@link #parseProperties(Properties, ConfigParseOptions)} but uses default 702 * parse options. 703 * @param properties 704 * a Java Properties object 705 * @return the parsed configuration 706 */ 707 public static Config parseProperties(Properties properties) { 708 return parseProperties(properties, ConfigParseOptions.defaults()); 709 } 710 711 /** 712 * Parses a Reader into a Config instance. Does not call 713 * {@link Config#resolve} or merge the parsed stream with any 714 * other configuration; this method parses a single stream and 715 * does nothing else. It does process "include" statements in 716 * the parsed stream, and may end up doing other IO due to those 717 * statements. 718 * 719 * @param reader 720 * the reader to parse 721 * @param options 722 * parse options to control how the reader is interpreted 723 * @return the parsed configuration 724 * @throws ConfigException on IO or parse errors 725 */ 726 public static Config parseReader(Reader reader, ConfigParseOptions options) { 727 return Parseable.newReader(reader, options).parse().toConfig(); 728 } 729 730 /** 731 * Parses a reader into a Config instance as with 732 * {@link #parseReader(Reader,ConfigParseOptions)} but always uses the 733 * default parse options. 734 * 735 * @param reader 736 * the reader to parse 737 * @return the parsed configuration 738 * @throws ConfigException on IO or parse errors 739 */ 740 public static Config parseReader(Reader reader) { 741 return parseReader(reader, ConfigParseOptions.defaults()); 742 } 743 744 /** 745 * Parses a URL into a Config instance. Does not call 746 * {@link Config#resolve} or merge the parsed stream with any 747 * other configuration; this method parses a single stream and 748 * does nothing else. It does process "include" statements in 749 * the parsed stream, and may end up doing other IO due to those 750 * statements. 751 * 752 * @param url 753 * the url to parse 754 * @param options 755 * parse options to control how the url is interpreted 756 * @return the parsed configuration 757 * @throws ConfigException on IO or parse errors 758 */ 759 public static Config parseURL(URL url, ConfigParseOptions options) { 760 return Parseable.newURL(url, options).parse().toConfig(); 761 } 762 763 /** 764 * Parses a url into a Config instance as with 765 * {@link #parseURL(URL,ConfigParseOptions)} but always uses the 766 * default parse options. 767 * 768 * @param url 769 * the url to parse 770 * @return the parsed configuration 771 * @throws ConfigException on IO or parse errors 772 */ 773 public static Config parseURL(URL url) { 774 return parseURL(url, ConfigParseOptions.defaults()); 775 } 776 777 /** 778 * Parses a file into a Config instance. Does not call 779 * {@link Config#resolve} or merge the file with any other 780 * configuration; this method parses a single file and does 781 * nothing else. It does process "include" statements in the 782 * parsed file, and may end up doing other IO due to those 783 * statements. 784 * 785 * @param file 786 * the file to parse 787 * @param options 788 * parse options to control how the file is interpreted 789 * @return the parsed configuration 790 * @throws ConfigException on IO or parse errors 791 */ 792 public static Config parseFile(File file, ConfigParseOptions options) { 793 return Parseable.newFile(file, options).parse().toConfig(); 794 } 795 796 /** 797 * Parses a file into a Config instance as with 798 * {@link #parseFile(File,ConfigParseOptions)} but always uses the 799 * default parse options. 800 * 801 * @param file 802 * the file to parse 803 * @return the parsed configuration 804 * @throws ConfigException on IO or parse errors 805 */ 806 public static Config parseFile(File file) { 807 return parseFile(file, ConfigParseOptions.defaults()); 808 } 809 810 /** 811 * Parses a file with a flexible extension. If the <code>fileBasename</code> 812 * already ends in a known extension, this method parses it according to 813 * that extension (the file's syntax must match its extension). If the 814 * <code>fileBasename</code> does not end in an extension, it parses files 815 * with all known extensions and merges whatever is found. 816 * 817 * <p> 818 * In the current implementation, the extension ".conf" forces 819 * {@link ConfigSyntax#CONF}, ".json" forces {@link ConfigSyntax#JSON}, and 820 * ".properties" forces {@link ConfigSyntax#PROPERTIES}. When merging files, 821 * ".conf" falls back to ".json" falls back to ".properties". 822 * 823 * <p> 824 * Future versions of the implementation may add additional syntaxes or 825 * additional extensions. However, the ordering (fallback priority) of the 826 * three current extensions will remain the same. 827 * 828 * <p> 829 * If <code>options</code> forces a specific syntax, this method only parses 830 * files with an extension matching that syntax. 831 * 832 * <p> 833 * If {@link ConfigParseOptions#getAllowMissing options.getAllowMissing()} 834 * is true, then no files have to exist; if false, then at least one file 835 * has to exist. 836 * 837 * @param fileBasename 838 * a filename with or without extension 839 * @param options 840 * parse options 841 * @return the parsed configuration 842 */ 843 public static Config parseFileAnySyntax(File fileBasename, 844 ConfigParseOptions options) { 845 return ConfigImpl.parseFileAnySyntax(fileBasename, options).toConfig(); 846 } 847 848 /** 849 * Like {@link #parseFileAnySyntax(File,ConfigParseOptions)} but always uses 850 * default parse options. 851 * 852 * @param fileBasename 853 * a filename with or without extension 854 * @return the parsed configuration 855 */ 856 public static Config parseFileAnySyntax(File fileBasename) { 857 return parseFileAnySyntax(fileBasename, ConfigParseOptions.defaults()); 858 } 859 860 /** 861 * Parses all resources on the classpath with the given name and merges them 862 * into a single <code>Config</code>. 863 * 864 * <p> 865 * If the resource name does not begin with a "/", it will have the supplied 866 * class's package added to it, in the same way as 867 * {@link java.lang.Class#getResource}. 868 * 869 * <p> 870 * Duplicate resources with the same name are merged such that ones returned 871 * earlier from {@link ClassLoader#getResources} fall back to (have higher 872 * priority than) the ones returned later. This implies that resources 873 * earlier in the classpath override those later in the classpath when they 874 * configure the same setting. However, in practice real applications may 875 * not be consistent about classpath ordering, so be careful. It may be best 876 * to avoid assuming too much. 877 * 878 * @param klass 879 * <code>klass.getClassLoader()</code> will be used to load 880 * resources, and non-absolute resource names will have this 881 * class's package added 882 * @param resource 883 * resource to look up, relative to <code>klass</code>'s package 884 * or absolute starting with a "/" 885 * @param options 886 * parse options 887 * @return the parsed configuration 888 */ 889 public static Config parseResources(Class<?> klass, String resource, 890 ConfigParseOptions options) { 891 return Parseable.newResources(klass, resource, options).parse() 892 .toConfig(); 893 } 894 895 /** 896 * Like {@link #parseResources(Class,String,ConfigParseOptions)} but always uses 897 * default parse options. 898 * 899 * @param klass 900 * <code>klass.getClassLoader()</code> will be used to load 901 * resources, and non-absolute resource names will have this 902 * class's package added 903 * @param resource 904 * resource to look up, relative to <code>klass</code>'s package 905 * or absolute starting with a "/" 906 * @return the parsed configuration 907 */ 908 public static Config parseResources(Class<?> klass, String resource) { 909 return parseResources(klass, resource, ConfigParseOptions.defaults()); 910 } 911 912 /** 913 * Parses classpath resources with a flexible extension. In general, this 914 * method has the same behavior as 915 * {@link #parseFileAnySyntax(File,ConfigParseOptions)} but for classpath 916 * resources instead, as in {@link #parseResources}. 917 * 918 * <p> 919 * There is a thorny problem with this method, which is that 920 * {@link java.lang.ClassLoader#getResources} must be called separately for 921 * each possible extension. The implementation ends up with separate lists 922 * of resources called "basename.conf" and "basename.json" for example. As a 923 * result, the ideal ordering between two files with different extensions is 924 * unknown; there is no way to figure out how to merge the two lists in 925 * classpath order. To keep it simple, the lists are simply concatenated, 926 * with the same syntax priorities as 927 * {@link #parseFileAnySyntax(File,ConfigParseOptions) parseFileAnySyntax()} 928 * - all ".conf" resources are ahead of all ".json" resources which are 929 * ahead of all ".properties" resources. 930 * 931 * @param klass 932 * class which determines the <code>ClassLoader</code> and the 933 * package for relative resource names 934 * @param resourceBasename 935 * a resource name as in {@link java.lang.Class#getResource}, 936 * with or without extension 937 * @param options 938 * parse options (class loader is ignored in favor of the one 939 * from klass) 940 * @return the parsed configuration 941 */ 942 public static Config parseResourcesAnySyntax(Class<?> klass, String resourceBasename, 943 ConfigParseOptions options) { 944 return ConfigImpl.parseResourcesAnySyntax(klass, resourceBasename, 945 options).toConfig(); 946 } 947 948 /** 949 * Like {@link #parseResourcesAnySyntax(Class,String,ConfigParseOptions)} 950 * but always uses default parse options. 951 * 952 * @param klass 953 * <code>klass.getClassLoader()</code> will be used to load 954 * resources, and non-absolute resource names will have this 955 * class's package added 956 * @param resourceBasename 957 * a resource name as in {@link java.lang.Class#getResource}, 958 * with or without extension 959 * @return the parsed configuration 960 */ 961 public static Config parseResourcesAnySyntax(Class<?> klass, String resourceBasename) { 962 return parseResourcesAnySyntax(klass, resourceBasename, ConfigParseOptions.defaults()); 963 } 964 965 /** 966 * Parses all resources on the classpath with the given name and merges them 967 * into a single <code>Config</code>. 968 * 969 * <p> 970 * This works like {@link java.lang.ClassLoader#getResource}, not like 971 * {@link java.lang.Class#getResource}, so the name never begins with a 972 * slash. 973 * 974 * <p> 975 * See {@link #parseResources(Class,String,ConfigParseOptions)} for full 976 * details. 977 * 978 * @param loader 979 * will be used to load resources by setting this loader on the 980 * provided options 981 * @param resource 982 * resource to look up 983 * @param options 984 * parse options (class loader is ignored) 985 * @return the parsed configuration 986 */ 987 public static Config parseResources(ClassLoader loader, String resource, 988 ConfigParseOptions options) { 989 return parseResources(resource, options.setClassLoader(loader)); 990 } 991 992 /** 993 * Like {@link #parseResources(ClassLoader,String,ConfigParseOptions)} but always uses 994 * default parse options. 995 * 996 * @param loader 997 * will be used to load resources 998 * @param resource 999 * resource to look up in the loader 1000 * @return the parsed configuration 1001 */ 1002 public static Config parseResources(ClassLoader loader, String resource) { 1003 return parseResources(loader, resource, ConfigParseOptions.defaults()); 1004 } 1005 1006 /** 1007 * Parses classpath resources with a flexible extension. In general, this 1008 * method has the same behavior as 1009 * {@link #parseFileAnySyntax(File,ConfigParseOptions)} but for classpath 1010 * resources instead, as in 1011 * {@link #parseResources(ClassLoader,String,ConfigParseOptions)}. 1012 * 1013 * <p> 1014 * {@link #parseResourcesAnySyntax(Class,String,ConfigParseOptions)} differs 1015 * in the syntax for the resource name, but otherwise see 1016 * {@link #parseResourcesAnySyntax(Class,String,ConfigParseOptions)} for 1017 * some details and caveats on this method. 1018 * 1019 * @param loader 1020 * class loader to look up resources in, will be set on options 1021 * @param resourceBasename 1022 * a resource name as in 1023 * {@link java.lang.ClassLoader#getResource}, with or without 1024 * extension 1025 * @param options 1026 * parse options (class loader ignored) 1027 * @return the parsed configuration 1028 */ 1029 public static Config parseResourcesAnySyntax(ClassLoader loader, String resourceBasename, 1030 ConfigParseOptions options) { 1031 return ConfigImpl.parseResourcesAnySyntax(resourceBasename, options.setClassLoader(loader)) 1032 .toConfig(); 1033 } 1034 1035 /** 1036 * Like {@link #parseResourcesAnySyntax(ClassLoader,String,ConfigParseOptions)} but always uses 1037 * default parse options. 1038 * 1039 * @param loader 1040 * will be used to load resources 1041 * @param resourceBasename 1042 * a resource name as in 1043 * {@link java.lang.ClassLoader#getResource}, with or without 1044 * extension 1045 * @return the parsed configuration 1046 */ 1047 public static Config parseResourcesAnySyntax(ClassLoader loader, String resourceBasename) { 1048 return parseResourcesAnySyntax(loader, resourceBasename, ConfigParseOptions.defaults()); 1049 } 1050 1051 /** 1052 * Like {@link #parseResources(ClassLoader,String,ConfigParseOptions)} but 1053 * uses thread's current context class loader if none is set in the 1054 * ConfigParseOptions. 1055 * @param resource the resource name 1056 * @param options parse options 1057 * @return the parsed configuration 1058 */ 1059 public static Config parseResources(String resource, ConfigParseOptions options) { 1060 ConfigParseOptions withLoader = ensureClassLoader(options, "parseResources"); 1061 return Parseable.newResources(resource, withLoader).parse().toConfig(); 1062 } 1063 1064 /** 1065 * Like {@link #parseResources(ClassLoader,String)} but uses thread's 1066 * current context class loader. 1067 * @param resource the resource name 1068 * @return the parsed configuration 1069 */ 1070 public static Config parseResources(String resource) { 1071 return parseResources(resource, ConfigParseOptions.defaults()); 1072 } 1073 1074 /** 1075 * Like 1076 * {@link #parseResourcesAnySyntax(ClassLoader,String,ConfigParseOptions)} 1077 * but uses thread's current context class loader. 1078 * @param resourceBasename the resource basename (no file type suffix) 1079 * @param options parse options 1080 * @return the parsed configuration 1081 */ 1082 public static Config parseResourcesAnySyntax(String resourceBasename, ConfigParseOptions options) { 1083 return ConfigImpl.parseResourcesAnySyntax(resourceBasename, options).toConfig(); 1084 } 1085 1086 /** 1087 * Like {@link #parseResourcesAnySyntax(ClassLoader,String)} but uses 1088 * thread's current context class loader. 1089 * @param resourceBasename the resource basename (no file type suffix) 1090 * @return the parsed configuration 1091 */ 1092 public static Config parseResourcesAnySyntax(String resourceBasename) { 1093 return parseResourcesAnySyntax(resourceBasename, ConfigParseOptions.defaults()); 1094 } 1095 1096 /** 1097 * Parse only any application replacement (specified by one of config.{resource,file,url}), returning 1098 * an empty Config if no overrides were set. 1099 * 1100 * @since 1.4.1 1101 * 1102 * @return a {@link java.util.Optional} containing any specified replacement, or {@link Optional#empty()} 1103 * if none was specified. 1104 */ 1105 public static java.util.Optional<Config> parseApplicationReplacement() { 1106 return parseApplicationReplacement(ConfigParseOptions.defaults()); 1107 } 1108 1109 /** 1110 * Like {@link #parseApplicationReplacement()} but allows you to specify a class loader 1111 * ti yse rather than the current context class loader. 1112 * 1113 * @since 1.4.1 1114 * 1115 * @param loader the class loader 1116 * @return a {@link java.util.Optional} containing any specified replacement, or {@link Optional#empty()} 1117 * if none was specified. 1118 */ 1119 public static java.util.Optional<Config> parseApplicationReplacement(ClassLoader loader) { 1120 return parseApplicationReplacement(ConfigParseOptions.defaults().setClassLoader(loader)); 1121 } 1122 1123 /** 1124 * Like {@link #parseApplicationReplacement()} but allows you to specify parse options. 1125 * 1126 * @since 1.4.1 1127 * 1128 * @param parseOptions parse options 1129 * @return a {@link java.util.Optional} containing any specified replacement, or {@link Optional#empty()} 1130 * if none was specified. 1131 */ 1132 public static java.util.Optional<Config> parseApplicationReplacement(ConfigParseOptions parseOptions) { 1133 final ConfigParseOptions withLoader = ensureClassLoader(parseOptions, "parseApplicationReplacement"); 1134 ClassLoader loader = withLoader.getClassLoader(); 1135 1136 int specified = 0; 1137 1138 // override application.conf with config.file, config.resource, 1139 // config.url if requested. 1140 String resource = System.getProperty("config.resource"); 1141 if (resource != null) 1142 specified += 1; 1143 String file = System.getProperty("config.file"); 1144 if (file != null) 1145 specified += 1; 1146 String url = System.getProperty("config.url"); 1147 if (url != null) 1148 specified += 1; 1149 1150 if (specified == 0) { 1151 return java.util.Optional.empty(); 1152 } else if (specified > 1) { 1153 throw new ConfigException.Generic("You set more than one of config.file='" + file 1154 + "', config.url='" + url + "', config.resource='" + resource 1155 + "'; don't know which one to use!"); 1156 } else { 1157 // the override file/url/resource MUST be present or it's an error 1158 ConfigParseOptions overrideOptions = parseOptions.setAllowMissing(false); 1159 if (resource != null) { 1160 if (resource.startsWith("/")) 1161 resource = resource.substring(1); 1162 // this deliberately does not parseResourcesAnySyntax; if 1163 // people want that they can use an include statement. 1164 return java.util.Optional.of(ConfigFactory.parseResources(loader, resource, overrideOptions)); 1165 } else if (file != null) { 1166 return java.util.Optional.of(ConfigFactory.parseFile(new File(file), overrideOptions)); 1167 } else { 1168 try { 1169 return java.util.Optional.of(ConfigFactory.parseURL(new URL(url), overrideOptions)); 1170 } catch (MalformedURLException e) { 1171 throw new ConfigException.Generic("Bad URL in config.url system property: '" 1172 + url + "': " + e.getMessage(), e); 1173 } 1174 } 1175 } 1176 1177 } 1178 1179 /** 1180 * Parses a string (which should be valid HOCON or JSON by default, or 1181 * the syntax specified in the options otherwise). 1182 * 1183 * @param s string to parse 1184 * @param options parse options 1185 * @return the parsed configuration 1186 */ 1187 public static Config parseString(String s, ConfigParseOptions options) { 1188 return Parseable.newString(s, options).parse().toConfig(); 1189 } 1190 1191 /** 1192 * Parses a string (which should be valid HOCON or JSON). 1193 * 1194 * @param s string to parse 1195 * @return the parsed configuration 1196 */ 1197 public static Config parseString(String s) { 1198 return parseString(s, ConfigParseOptions.defaults()); 1199 } 1200 1201 /** 1202 * Creates a {@code Config} based on a {@link java.util.Map} from paths to 1203 * plain Java values. Similar to 1204 * {@link ConfigValueFactory#fromMap(Map,String)}, except the keys in the 1205 * map are path expressions, rather than keys; and correspondingly it 1206 * returns a {@code Config} instead of a {@code ConfigObject}. This is more 1207 * convenient if you are writing literal maps in code, and less convenient 1208 * if you are getting your maps from some data source such as a parser. 1209 * 1210 * <p> 1211 * An exception will be thrown (and it is a bug in the caller of the method) 1212 * if a path is both an object and a value, for example if you had both 1213 * "a=foo" and "a.b=bar", then "a" is both the string "foo" and the parent 1214 * object of "b". The caller of this method should ensure that doesn't 1215 * happen. 1216 * 1217 * @param values map from paths to plain Java objects 1218 * @param originDescription 1219 * description of what this map represents, like a filename, or 1220 * "default settings" (origin description is used in error 1221 * messages) 1222 * @return the map converted to a {@code Config} 1223 */ 1224 public static Config parseMap(Map<String, ? extends Object> values, 1225 String originDescription) { 1226 return ConfigImpl.fromPathMap(values, originDescription).toConfig(); 1227 } 1228 1229 /** 1230 * See the other overload of {@link #parseMap(Map, String)} for details, 1231 * this one just uses a default origin description. 1232 * 1233 * @param values map from paths to plain Java values 1234 * @return the map converted to a {@code Config} 1235 */ 1236 public static Config parseMap(Map<String, ? extends Object> values) { 1237 return parseMap(values, null); 1238 } 1239 1240 private static ConfigLoadingStrategy getConfigLoadingStrategy() { 1241 String className = System.getProperties().getProperty(STRATEGY_PROPERTY_NAME); 1242 1243 if (className != null) { 1244 try { 1245 return Class.forName(className).asSubclass(ConfigLoadingStrategy.class).getDeclaredConstructor().newInstance(); 1246 } catch (InvocationTargetException e) { 1247 Throwable cause = e.getCause(); 1248 if (cause == null) throw new ConfigException.BugOrBroken("Failed to load strategy: " + className, e); 1249 else throw new ConfigException.BugOrBroken("Failed to load strategy: " + className, cause); 1250 } catch (Throwable e) { 1251 throw new ConfigException.BugOrBroken("Failed to load strategy: " + className, e); 1252 } 1253 } else { 1254 return new DefaultConfigLoadingStrategy(); 1255 } 1256 } 1257 1258 private static Boolean getOverrideWithEnv() { 1259 String overrideWithEnv = System.getProperties().getProperty(OVERRIDE_WITH_ENV_PROPERTY_NAME); 1260 1261 return Boolean.parseBoolean(overrideWithEnv); 1262 } 1263}