@@ -40,7 +40,7 @@ public class ConfigBeanImpl {
4040 * @param clazz class of the bean
4141 * @return the bean instance
4242 */
43- public static <T > T createInternal (Config config , Class <T > clazz ) {
43+ public static <T > T createInternal (Config config , Class <T > clazz , boolean allowUnknownConfigKeys ) {
4444 if (((SimpleConfig )config ).root ().resolveStatus () != ResolveStatus .RESOLVED )
4545 throw new ConfigException .NotResolved (
4646 "need to Config#resolve() a config before using it to initialize a bean, see the API docs for Config#resolve()" );
@@ -76,10 +76,26 @@ public static <T> T createInternal(Config config, Class<T> clazz) {
7676 }
7777 beanProps .add (beanProp );
7878 }
79+ Set <String > beanPropNames = new HashSet <String >();
80+ for (PropertyDescriptor beanProp : beanProps ) {
81+ beanPropNames .add (beanProp .getName ());
82+ }
7983
8084 // Try to throw all validation issues at once (this does not comprehensively
8185 // find every issue, but it should find common ones).
8286 List <ConfigException .ValidationProblem > problems = new ArrayList <ConfigException .ValidationProblem >();
87+ if (!allowUnknownConfigKeys ) {
88+ for (Map .Entry <String , String > nameEntry : originalNames .entrySet ()) {
89+ String camelName = nameEntry .getKey ();
90+ if (!beanPropNames .contains (camelName )) {
91+ AbstractConfigValue configValue = configProps .get (camelName );
92+ problems .add (new ConfigException .ValidationProblem (
93+ Path .newKey (nameEntry .getValue ()).render (),
94+ configValue .origin (),
95+ "Unknown config setting" ));
96+ }
97+ }
98+ }
8399 for (PropertyDescriptor beanProp : beanProps ) {
84100 Method setter = beanProp .getWriteMethod ();
85101 Class <?> parameterClass = setter .getParameterTypes ()[0 ];
@@ -121,7 +137,8 @@ public static <T> T createInternal(Config config, Class<T> clazz) {
121137 // Otherwise, raise a {@link Missing} exception right here
122138 throw new ConfigException .Missing (beanProp .getName ());
123139 }
124- Object unwrapped = getValue (clazz , parameterType , parameterClass , config , configPropName );
140+ Object unwrapped = getValue (clazz , parameterType , parameterClass , config , configPropName ,
141+ allowUnknownConfigKeys );
125142 setter .invoke (bean , unwrapped );
126143 }
127144 return bean ;
@@ -145,7 +162,7 @@ public static <T> T createInternal(Config config, Class<T> clazz) {
145162 // types plus you can always use Object, ConfigValue, Config,
146163 // ConfigObject, etc. as an escape hatch.
147164 private static Object getValue (Class <?> beanClass , Type parameterType , Class <?> parameterClass , Config config ,
148- String configPropName ) {
165+ String configPropName , boolean allowUnknownConfigKeys ) {
149166 if (parameterClass == Boolean .class || parameterClass == boolean .class ) {
150167 return config .getBoolean (configPropName );
151168 } else if (parameterClass == Integer .class || parameterClass == int .class ) {
@@ -163,9 +180,11 @@ private static Object getValue(Class<?> beanClass, Type parameterType, Class<?>
163180 } else if (parameterClass == Object .class ) {
164181 return config .getAnyRef (configPropName );
165182 } else if (parameterClass == List .class ) {
166- return getListValue (beanClass , parameterType , parameterClass , config , configPropName );
183+ return getListValue (beanClass , parameterType , parameterClass , config , configPropName ,
184+ allowUnknownConfigKeys );
167185 } else if (parameterClass == Set .class ) {
168- return getSetValue (beanClass , parameterType , parameterClass , config , configPropName );
186+ return getSetValue (beanClass , parameterType , parameterClass , config , configPropName ,
187+ allowUnknownConfigKeys );
169188 } else if (parameterClass == Map .class ) {
170189 // we could do better here, but right now we don't.
171190 Type [] typeArgs = ((ParameterizedType )parameterType ).getActualTypeArguments ();
@@ -186,17 +205,20 @@ private static Object getValue(Class<?> beanClass, Type parameterType, Class<?>
186205 Enum enumValue = config .getEnum ((Class <Enum >) parameterClass , configPropName );
187206 return enumValue ;
188207 } else if (hasAtLeastOneBeanProperty (parameterClass )) {
189- return createInternal (config .getConfig (configPropName ), parameterClass );
208+ return createInternal (config .getConfig (configPropName ), parameterClass , allowUnknownConfigKeys );
190209 } else {
191210 throw new ConfigException .BadBean ("Bean property " + configPropName + " of class " + beanClass .getName () + " has unsupported type " + parameterType );
192211 }
193212 }
194213
195- private static Object getSetValue (Class <?> beanClass , Type parameterType , Class <?> parameterClass , Config config , String configPropName ) {
196- return new HashSet ((List ) getListValue (beanClass , parameterType , parameterClass , config , configPropName ));
214+ private static Object getSetValue (Class <?> beanClass , Type parameterType , Class <?> parameterClass , Config config ,
215+ String configPropName , boolean allowUnknownConfigKeys ) {
216+ return new HashSet ((List ) getListValue (beanClass , parameterType , parameterClass , config , configPropName ,
217+ allowUnknownConfigKeys ));
197218 }
198219
199- private static Object getListValue (Class <?> beanClass , Type parameterType , Class <?> parameterClass , Config config , String configPropName ) {
220+ private static Object getListValue (Class <?> beanClass , Type parameterType , Class <?> parameterClass , Config config ,
221+ String configPropName , boolean allowUnknownConfigKeys ) {
200222 Type elementType = ((ParameterizedType )parameterType ).getActualTypeArguments ()[0 ];
201223
202224 if (elementType == Boolean .class ) {
@@ -229,7 +251,7 @@ private static Object getListValue(Class<?> beanClass, Type parameterType, Class
229251 List <Object > beanList = new ArrayList <Object >();
230252 List <? extends Config > configList = config .getConfigList (configPropName );
231253 for (Config listMember : configList ) {
232- beanList .add (createInternal (listMember , (Class <?>) elementType ));
254+ beanList .add (createInternal (listMember , (Class <?>) elementType , allowUnknownConfigKeys ));
233255 }
234256 return beanList ;
235257 } else {
0 commit comments