001/** 002 * Copyright (C) 2011-2012 Typesafe Inc. <http://typesafe.com> 003 */ 004package com.typesafe.config; 005 006/** 007 * A set of options related to resolving substitutions. Substitutions use the 008 * <code>${foo.bar}</code> syntax and are documented in the <a 009 * href="https://github.com/lightbend/config/blob/main/HOCON.md">HOCON</a> 010 * spec. 011 * <p> 012 * Typically this class would be used with the method 013 * {@link Config#resolve(ConfigResolveOptions)}. 014 * <p> 015 * This object is immutable, so the "setters" return a new object. 016 * <p> 017 * Here is an example of creating a custom {@code ConfigResolveOptions}: 018 * 019 * <pre> 020 * ConfigResolveOptions options = ConfigResolveOptions.defaults() 021 * .setUseSystemEnvironment(false) 022 * </pre> 023 * <p> 024 * In addition to {@link ConfigResolveOptions#defaults}, there's a prebuilt 025 * {@link ConfigResolveOptions#noSystem} which avoids looking at any system 026 * environment variables or other external system information. (Right now, 027 * environment variables are the only example.) 028 */ 029public final class ConfigResolveOptions { 030 private final boolean useSystemEnvironment; 031 private final boolean allowUnresolved; 032 private final ConfigResolver resolver; 033 034 private ConfigResolveOptions(boolean useSystemEnvironment, boolean allowUnresolved, 035 ConfigResolver resolver) { 036 this.useSystemEnvironment = useSystemEnvironment; 037 this.allowUnresolved = allowUnresolved; 038 this.resolver = resolver; 039 } 040 041 /** 042 * Returns the default resolve options. By default the system environment 043 * will be used and unresolved substitutions are not allowed. 044 * 045 * @return the default resolve options 046 */ 047 public static ConfigResolveOptions defaults() { 048 return new ConfigResolveOptions(true, false, NULL_RESOLVER); 049 } 050 051 /** 052 * Returns resolve options that disable any reference to "system" data 053 * (currently, this means environment variables). 054 * 055 * @return the resolve options with env variables disabled 056 */ 057 public static ConfigResolveOptions noSystem() { 058 return defaults().setUseSystemEnvironment(false); 059 } 060 061 /** 062 * Returns options with use of environment variables set to the given value. 063 * 064 * @param value 065 * true to resolve substitutions falling back to environment 066 * variables. 067 * @return options with requested setting for use of environment variables 068 */ 069 public ConfigResolveOptions setUseSystemEnvironment(boolean value) { 070 return new ConfigResolveOptions(value, allowUnresolved, resolver); 071 } 072 073 /** 074 * Returns whether the options enable use of system environment variables. 075 * This method is mostly used by the config lib internally, not by 076 * applications. 077 * 078 * @return true if environment variables should be used 079 */ 080 public boolean getUseSystemEnvironment() { 081 return useSystemEnvironment; 082 } 083 084 /** 085 * Returns options with "allow unresolved" set to the given value. By 086 * default, unresolved substitutions are an error. If unresolved 087 * substitutions are allowed, then a future attempt to use the unresolved 088 * value may fail, but {@link Config#resolve(ConfigResolveOptions)} itself 089 * will not throw. 090 * 091 * @param value 092 * true to silently ignore unresolved substitutions. 093 * @return options with requested setting for whether to allow substitutions 094 * @since 1.2.0 095 */ 096 public ConfigResolveOptions setAllowUnresolved(boolean value) { 097 return new ConfigResolveOptions(useSystemEnvironment, value, resolver); 098 } 099 100 /** 101 * Returns options where the given resolver used as a fallback if a 102 * reference cannot be otherwise resolved. This resolver will only be called 103 * after resolution has failed to substitute with a value from within the 104 * config itself and with any other resolvers that have been appended before 105 * this one. Multiple resolvers can be added using, 106 * 107 * <pre> 108 * ConfigResolveOptions options = ConfigResolveOptions.defaults() 109 * .appendResolver(primary) 110 * .appendResolver(secondary) 111 * .appendResolver(tertiary); 112 * </pre> 113 * 114 * With this config unresolved references will first be resolved with the 115 * primary resolver, if that fails then the secondary, and finally if that 116 * also fails the tertiary. 117 * 118 * If all fallbacks fail to return a substitution "allow unresolved" 119 * determines whether resolution fails or continues. 120 *` 121 * @param value the resolver to fall back to 122 * @return options that use the given resolver as a fallback 123 * @since 1.3.2 124 */ 125 public ConfigResolveOptions appendResolver(ConfigResolver value) { 126 if (value == null) { 127 throw new ConfigException.BugOrBroken("null resolver passed to appendResolver"); 128 } else if (value == this.resolver) { 129 return this; 130 } else { 131 return new ConfigResolveOptions(useSystemEnvironment, allowUnresolved, 132 this.resolver.withFallback(value)); 133 } 134 } 135 136 /** 137 * Returns the resolver to use as a fallback if a substitution cannot be 138 * otherwise resolved. Never returns null. This method is mostly used by the 139 * config lib internally, not by applications. 140 * 141 * @return the non-null fallback resolver 142 * @since 1.3.2 143 */ 144 public ConfigResolver getResolver() { 145 return this.resolver; 146 } 147 148 /** 149 * Returns whether the options allow unresolved substitutions. This method 150 * is mostly used by the config lib internally, not by applications. 151 * 152 * @return true if unresolved substitutions are allowed 153 * @since 1.2.0 154 */ 155 public boolean getAllowUnresolved() { 156 return allowUnresolved; 157 } 158 159 /** 160 * Singleton resolver that never resolves paths. 161 */ 162 private static final ConfigResolver NULL_RESOLVER = new ConfigResolver() { 163 164 @Override 165 public ConfigValue lookup(String path) { 166 return null; 167 } 168 169 @Override 170 public ConfigResolver withFallback(ConfigResolver fallback) { 171 return fallback; 172 } 173 174 }; 175 176}