7070
7171/**
7272 * Extension to enable config injection in CDI container (all of {@link io.helidon.config.Config},
73- * {@link org.eclipse.microprofile.config.Config} and {@link ConfigProperty}).
73+ * {@link org.eclipse.microprofile.config.Config} and {@link ConfigProperty} and {@link ConfigProperties} ).
7474 */
7575public class ConfigCdiExtension implements Extension {
7676 private static final Logger LOGGER = Logger .getLogger (ConfigCdiExtension .class .getName ());
@@ -248,10 +248,19 @@ private Object produce(InjectionPoint ip) {
248248 + " container initialization. This will not work nicely with Graal native-image" );
249249 }
250250
251- return produce (configKey , ip .getType (), defaultValue (annotation ));
251+ return produce (configKey , ip .getType (), defaultValue (annotation ), configKey . equals ( fullPath . replace ( '$' , '.' )) );
252252 }
253253
254- private Object produce (String configKey , Type type , String defaultValue ) {
254+ /*
255+ * Produce configuration value from injection point.
256+ *
257+ * @param configKey actual configuration key to find
258+ * @param type type of the injected field/parameter
259+ * @param defaultValue default value to be used
260+ * @param defaultConfigKey whether the configKey is constructed from class name and field
261+ * @return produced value to be injected
262+ */
263+ private Object produce (String configKey , Type type , String defaultValue , boolean defaultConfigKey ) {
255264 /*
256265 Supported types
257266 group x:
@@ -287,15 +296,19 @@ any java class (except for parameterized types)
287296 }
288297 }
289298
290- Object value = configValue (config , fieldTypes , configKey , defaultValue );
299+ Object value = configValue (config , fieldTypes , configKey , defaultValue , defaultConfigKey );
291300
292301 if (value == null ) {
293302 throw new NoSuchElementException ("Cannot find value for key: " + configKey );
294303 }
295304 return value ;
296305 }
297306
298- private Object configValue (Config config , FieldTypes fieldTypes , String configKey , String defaultValue ) {
307+ private Object configValue (Config config ,
308+ FieldTypes fieldTypes ,
309+ String configKey ,
310+ String defaultValue ,
311+ boolean defaultConfigKey ) {
299312 Class <?> type0 = fieldTypes .field0 ().rawType ();
300313 Class <?> type1 = fieldTypes .field1 ().rawType ();
301314 Class <?> type2 = fieldTypes .field2 ().rawType ();
@@ -307,6 +320,7 @@ private Object configValue(Config config, FieldTypes fieldTypes, String configKe
307320 // generic declaration
308321 return parameterizedConfigValue (config ,
309322 configKey ,
323+ defaultConfigKey ,
310324 defaultValue ,
311325 type0 ,
312326 type1 ,
@@ -371,6 +385,7 @@ private static <T> T convert(String key, Config config, String value, Class<T> t
371385
372386 private static Object parameterizedConfigValue (Config config ,
373387 String configKey ,
388+ boolean defaultConfigKey ,
374389 String defaultValue ,
375390 Class <?> rawType ,
376391 Class <?> typeArg ,
@@ -382,6 +397,7 @@ private static Object parameterizedConfigValue(Config config,
382397 return Optional
383398 .ofNullable (parameterizedConfigValue (config ,
384399 configKey ,
400+ defaultConfigKey ,
385401 defaultValue ,
386402 typeArg ,
387403 typeArg2 ,
@@ -395,17 +411,23 @@ private static Object parameterizedConfigValue(Config config,
395411 } else {
396412 return (Supplier <?>) () -> parameterizedConfigValue (config ,
397413 configKey ,
414+ defaultConfigKey ,
398415 defaultValue ,
399416 typeArg ,
400417 typeArg2 ,
401418 typeArg2 );
402419 }
403420 } else if (Map .class .isAssignableFrom (rawType )) {
421+ // config key we have should serve as a prefix, and the properties should have it removed
422+ // similar to what the original io.helidon.config.Config.get(configKey).detach()
404423 Map <String , String > result = new HashMap <>();
405424 config .getPropertyNames ()
406425 .forEach (name -> {
407- // workaround for race condition (if key disappears from source after we call getPropertyNames
408- config .getOptionalValue (name , String .class ).ifPresent (value -> result .put (name , value ));
426+ if (defaultConfigKey || name .startsWith (configKey )) {
427+ String key = removePrefix (configKey , defaultConfigKey , name );
428+ // workaround for race condition (if key disappears from source after we call getPropertyNames)
429+ config .getOptionalValue (name , String .class ).ifPresent (value -> result .put (key , value ));
430+ }
409431 });
410432 return result ;
411433 } else if (Set .class .isAssignableFrom (rawType )) {
@@ -416,6 +438,18 @@ private static Object parameterizedConfigValue(Config config,
416438 }
417439 }
418440
441+ private static String removePrefix (String prefix , boolean defaultConfigKey , String key ) {
442+ if (defaultConfigKey ) {
443+ return key ;
444+ }
445+
446+ String intermediate = key .substring (prefix .length ());
447+ if (intermediate .startsWith ("." )) {
448+ return intermediate .substring (1 );
449+ }
450+ return intermediate ;
451+ }
452+
419453 static String [] toArray (String stringValue ) {
420454 String [] values = SPLIT_PATTERN .split (stringValue , -1 );
421455
0 commit comments