11/*
2- * Copyright (c) 2019, 2024 Oracle and/or its affiliates.
2+ * Copyright (c) 2019, 2025 Oracle and/or its affiliates.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
1515 */
1616package io .helidon .config ;
1717
18+ import java .util .ArrayList ;
1819import java .util .HashMap ;
1920import java .util .HashSet ;
2021import java .util .List ;
2122import java .util .Map ;
23+ import java .util .Optional ;
2224import java .util .ServiceLoader ;
2325import java .util .Set ;
2426import java .util .function .Function ;
27+ import java .util .stream .Collectors ;
2528
2629import io .helidon .common .HelidonServiceLoader ;
2730import io .helidon .common .Weight ;
3538import io .helidon .config .spi .PollingStrategyProvider ;
3639import io .helidon .config .spi .RetryPolicy ;
3740import io .helidon .config .spi .RetryPolicyProvider ;
41+ import io .helidon .service .registry .Services ;
3842
3943/**
4044 * Access to Java service loaders for config sources, retry policies and polling strategies.
4145 */
4246final class MetaProviders {
43- private static final List <ConfigSourceProvider > CONFIG_SOURCE_PROVIDERS ;
4447 private static final List <RetryPolicyProvider > RETRY_POLICY_PROVIDERS ;
4548 private static final List <PollingStrategyProvider > POLLING_STRATEGY_PROVIDERS ;
4649 private static final List <ChangeWatcherProvider > CHANGE_WATCHER_PROVIDERS ;
4750 private static final List <OverrideSourceProvider > OVERRIDE_SOURCE_PROVIDERS ;
4851
49- private static final Set <String > SUPPORTED_CONFIG_SOURCES = new HashSet <>();
5052 private static final Set <String > SUPPORTED_RETRY_POLICIES = new HashSet <>();
5153 private static final Set <String > SUPPORTED_POLLING_STRATEGIES = new HashSet <>();
5254 private static final Set <String > SUPPORTED_CHANGE_WATCHERS = new HashSet <>();
5355 private static final Set <String > SUPPORTED_OVERRIDE_SOURCES = new HashSet <>();
5456
5557 static {
56- CONFIG_SOURCE_PROVIDERS = HelidonServiceLoader
57- .builder (ServiceLoader .load (ConfigSourceProvider .class ))
58- .addService (new BuiltInConfigSourcesProvider ())
59- .build ()
60- .asList ();
61-
62- CONFIG_SOURCE_PROVIDERS .stream ()
63- .map (ConfigSourceProvider ::supported )
64- .forEach (SUPPORTED_CONFIG_SOURCES ::addAll );
65-
6658 RETRY_POLICY_PROVIDERS = HelidonServiceLoader
6759 .builder (ServiceLoader .load (RetryPolicyProvider .class ))
6860 .addService (new BuiltInRetryPolicyProvider ())
@@ -93,7 +85,6 @@ final class MetaProviders {
9385 .map (ChangeWatcherProvider ::supported )
9486 .forEach (SUPPORTED_CHANGE_WATCHERS ::addAll );
9587
96-
9788 OVERRIDE_SOURCE_PROVIDERS = HelidonServiceLoader
9889 .builder (ServiceLoader .load (OverrideSourceProvider .class ))
9990 .addService (new BuiltinOverrideSourceProvider ())
@@ -108,22 +99,43 @@ final class MetaProviders {
10899 private MetaProviders () {
109100 }
110101
102+ public static ChangeWatcher <?> changeWatcher (String type , Config config ) {
103+ return CHANGE_WATCHER_PROVIDERS .stream ()
104+ .filter (provider -> provider .supports (type ))
105+ .findFirst ()
106+ .map (provider -> provider .create (type , config ))
107+ .orElseThrow (() -> new MetaConfigException ("Change watcher of type " + type + " is not supported."
108+ + " Supported types: " + SUPPORTED_CHANGE_WATCHERS ));
109+ }
110+
111111 static ConfigSource configSource (String type , Config config ) {
112- return CONFIG_SOURCE_PROVIDERS .stream ()
112+ var all = allProviders ();
113+ var supported = all .stream ()
114+ .map (ConfigSourceProvider ::supported )
115+ .flatMap (Set ::stream )
116+ .collect (Collectors .toUnmodifiableSet ());
117+
118+ return all .stream ()
113119 .filter (provider -> provider .supports (type ))
114120 .findFirst ()
115121 .map (provider -> provider .create (type , config ))
122+ .or (() -> findSourceFromRegistry (type ))
116123 .orElseThrow (() -> new MetaConfigException ("Config source of type " + type + " is not supported."
117- + " Supported types: " + SUPPORTED_CONFIG_SOURCES ));
124+ + " Supported types: " + supported ));
118125 }
119126
120127 static List <ConfigSource > configSources (String type , Config sourceProperties ) {
121- return CONFIG_SOURCE_PROVIDERS .stream ()
128+ var all = allProviders ();
129+ var supported = all .stream ()
130+ .map (ConfigSourceProvider ::supported )
131+ .flatMap (Set ::stream )
132+ .collect (Collectors .toUnmodifiableSet ());
133+ return all .stream ()
122134 .filter (provider -> provider .supports (type ))
123135 .findFirst ()
124136 .map (provider -> provider .createMulti (type , sourceProperties ))
125137 .orElseThrow (() -> new MetaConfigException ("Config source of type " + type + " is not supported."
126- + " Supported types: " + SUPPORTED_CONFIG_SOURCES ));
138+ + " Supported types: " + supported ));
127139 }
128140
129141 static OverrideSource overrideSource (String type , Config config ) {
@@ -132,7 +144,7 @@ static OverrideSource overrideSource(String type, Config config) {
132144 .findFirst ()
133145 .map (provider -> provider .create (type , config ))
134146 .orElseThrow (() -> new MetaConfigException ("Config source of type " + type + " is not supported."
135- + " Supported types: " + SUPPORTED_OVERRIDE_SOURCES ));
147+ + " Supported types: " + SUPPORTED_OVERRIDE_SOURCES ));
136148 }
137149
138150 static PollingStrategy pollingStrategy (String type , Config config ) {
@@ -141,7 +153,7 @@ static PollingStrategy pollingStrategy(String type, Config config) {
141153 .findFirst ()
142154 .map (provider -> provider .create (type , config ))
143155 .orElseThrow (() -> new MetaConfigException ("Polling strategy of type " + type + " is not supported."
144- + " Supported types: " + SUPPORTED_POLLING_STRATEGIES ));
156+ + " Supported types: " + SUPPORTED_POLLING_STRATEGIES ));
145157 }
146158
147159 static RetryPolicy retryPolicy (String type , Config config ) {
@@ -150,16 +162,17 @@ static RetryPolicy retryPolicy(String type, Config config) {
150162 .findFirst ()
151163 .map (provider -> provider .create (type , config ))
152164 .orElseThrow (() -> new MetaConfigException ("Retry policy of type " + type + " is not supported."
153- + " Supported types: " + SUPPORTED_RETRY_POLICIES ));
165+ + " Supported types: " + SUPPORTED_RETRY_POLICIES ));
154166 }
155167
156- public static ChangeWatcher <?> changeWatcher (String type , Config config ) {
157- return CHANGE_WATCHER_PROVIDERS .stream ()
158- .filter (provider -> provider .supports (type ))
159- .findFirst ()
160- .map (provider -> provider .create (type , config ))
161- .orElseThrow (() -> new MetaConfigException ("Change watcher of type " + type + " is not supported."
162- + " Supported types: " + SUPPORTED_CHANGE_WATCHERS ));
168+ private static Optional <ConfigSource > findSourceFromRegistry (String type ) {
169+ return Services .firstNamed (ConfigSource .class , type );
170+ }
171+
172+ private static List <ConfigSourceProvider > allProviders () {
173+ var result = new ArrayList <>(Services .all (ConfigSourceProvider .class ));
174+ result .add (new BuiltInConfigSourcesProvider ());
175+ return result ;
163176 }
164177
165178 @ Weight (0 )
0 commit comments