001package io.avaje.config;
002
003import java.math.BigDecimal;
004import java.net.URL;
005import java.util.List;
006import java.util.Optional;
007import java.util.Properties;
008import java.util.Set;
009import java.util.function.Consumer;
010
011/**
012 * Configuration API for accessing property values and registering onChange listeners.
013 *
014 * <h3>Examples</h3>
015 * <pre>{@code
016 *
017 *  int port = Config.getInt("app.port", 8090);
018 *
019 *  String topicName = Config.get("app.topic.name");
020 *
021 *  List<Integer> codes = Config.getList().ofInt("my.codes", 42, 54);
022 *
023 * }</pre>
024 */
025public interface Configuration {
026
027  /**
028   * Return the loaded properties as standard Properties map.
029   */
030  Properties asProperties();
031
032  /**
033   * Return a required configuration value as String.
034   * <p>
035   * IllegalStateException is thrown if the value is not defined in configuration.
036   * </p>
037   *
038   * @param key The configuration key
039   * @return The configured value
040   */
041  String get(String key);
042
043  /**
044   * Return a configuration string value with a given default.
045   *
046   * @param key          The configuration key
047   * @param defaultValue The default value used
048   * @return The configured or default value
049   */
050  String get(String key, String defaultValue);
051
052  /**
053   * Return a configuration value that might not exist.
054   *
055   * @param key The configuration key
056   * @return The configured value wrapped as optional
057   */
058  Optional<String> getOptional(String key);
059
060  /**
061   * Return a required boolean configuration value.
062   * <p>
063   * IllegalStateException is thrown if the value is not defined in configuration.
064   * </p>
065   *
066   * @param key The configuration key
067   * @return The configured value
068   */
069  boolean getBool(String key);
070
071  /**
072   * Return a configuration value as boolean given a default value.
073   *
074   * @param key          The configuration key
075   * @param defaultValue The default value used
076   * @return The configured or default value
077   */
078  boolean getBool(String key, boolean defaultValue);
079
080  /**
081   * Return a required int configuration value.
082   * <p>
083   * IllegalStateException is thrown if the value is not defined in configuration.
084   * </p>
085   *
086   * @param key The configuration key
087   * @return The configured value
088   */
089  int getInt(String key);
090
091  /**
092   * Return a configuration value as int given a default value.
093   *
094   * @param key          The configuration key
095   * @param defaultValue The default value used
096   * @return The configured or default value
097   */
098  int getInt(String key, int defaultValue);
099
100  /**
101   * Return a required long configuration value.
102   * <p>
103   * IllegalStateException is thrown if the value is not defined in configuration.
104   * </p>
105   *
106   * @param key The configuration key
107   * @return The configured value
108   */
109  long getLong(String key);
110
111  /**
112   * Return a configuration value as long given a default value.
113   *
114   * @param key          The configuration key
115   * @param defaultValue The default value used
116   * @return The configured or default value
117   */
118  long getLong(String key, long defaultValue);
119
120  /**
121   * Return a decimal configuration value.
122   *
123   * @param key The configuration key
124   * @return The configured value
125   */
126  BigDecimal getDecimal(String key);
127
128  /**
129   * Return a decimal configuration value with a default value.
130   * <p>
131   * IllegalStateException is thrown if the value is not defined in configuration.
132   * </p>
133   *
134   * @param key          The configuration key
135   * @param defaultValue The default value
136   * @return The configured value
137   */
138  BigDecimal getDecimal(String key, String defaultValue);
139
140  /**
141   * Return a URL configuration value.
142   *
143   * @param key The configuration key
144   * @return The configured value
145   */
146  URL getURL(String key);
147
148  /**
149   * Return a URL configuration value with a default value.
150   * <p>
151   * IllegalStateException is thrown if the value is not defined in configuration.
152   * </p>
153   *
154   * @param key          The configuration key
155   * @param defaultValue The default value
156   * @return The configured value
157   */
158  URL getURL(String key, String defaultValue);
159
160  /**
161   * Return the enum configuration value.
162   * <p>
163   * IllegalStateException is thrown if the value is not defined in configuration.
164   * </p>
165   *
166   * @param type The enum type
167   * @param key  The configuration key
168   * @return The configured value
169   */
170  <T extends Enum<T>> T getEnum(Class<T> type, String key);
171
172  /**
173   * Return the enum configuration value with a default value.
174   *
175   * @param type         The enum type
176   * @param key          The configuration key
177   * @param defaultValue The default value
178   * @return The configured value
179   */
180  <T extends Enum<T>> T getEnum(Class<T> type, String key, T defaultValue);
181
182  /**
183   * Return a List of values configured.
184   *
185   * <pre>{@code
186   *
187   *  List<Integer> codes = Config.getList().ofInt("my.codes", 97, 45);
188   *
189   * }</pre>
190   */
191  ListValue getList();
192
193  /**
194   * Return a Set of values configured.
195   *
196   * <pre>{@code
197   *
198   *  Set<String> operations = Config.getSet().of("my.operations", "put","delete");
199   *
200   * }</pre>
201   */
202  SetValue getSet();
203
204  /**
205   * Set a configuration value.
206   * <p>
207   * This will fire an configuration callback listeners that are registered
208   * for this key.
209   * </p>
210   */
211  void setProperty(String key, String value);
212
213  /**
214   * Register a callback for a change to the given configuration key.
215   *
216   * @param key      The configuration key we want to detect changes to
217   * @param callback The callback handling to fire when the configuration changes.
218   */
219  void onChange(String key, Consumer<String> callback);
220
221  /**
222   * Register a callback for a change to the given configuration key as an Int value.
223   *
224   * @param key      The configuration key we want to detect changes to
225   * @param callback The callback handling to fire when the configuration changes.
226   */
227  void onChangeInt(String key, Consumer<Integer> callback);
228
229  /**
230   * Register a callback for a change to the given configuration key as an Long value.
231   *
232   * @param key      The configuration key we want to detect changes to
233   * @param callback The callback handling to fire when the configuration changes.
234   */
235  void onChangeLong(String key, Consumer<Long> callback);
236
237  /**
238   * Register a callback for a change to the given configuration key as an Boolean value.
239   *
240   * @param key      The configuration key we want to detect changes to
241   * @param callback The callback handling to fire when the configuration changes.
242   */
243  void onChangeBool(String key, Consumer<Boolean> callback);
244
245  /**
246   * Put the loaded properties into System properties.
247   */
248  void loadIntoSystemProperties();
249
250  /**
251   * Return the number of configuration properties.
252   */
253  int size();
254
255  /**
256   * Schedule a task to run periodically with a given delay and period.
257   *
258   * @param delay  delay in milliseconds before task is to be executed.
259   * @param period time in milliseconds between successive task executions.
260   * @param task   task to be scheduled.
261   */
262  void schedule(long delay, long period, Runnable task);
263
264  /**
265   * Return a copy of the properties with 'eval' run on all the values.
266   */
267  Properties eval(Properties properties);
268
269  /**
270   * Expression evaluation.
271   */
272  interface ExpressionEval {
273
274    /**
275     * Evaluate a configuration expression.
276     */
277    String eval(String expression);
278  }
279
280  /**
281   * Return a List of values for a configuration key.
282   *
283   * <h3>Example</h3>
284   * <pre>{@code
285   *
286   *  List<Integer> codes = Config.getList().ofInt("my.codes", 42, 54);
287   *
288   * }</pre>
289   */
290  interface ListValue {
291
292    /**
293     * Return the list of values for the key returning an empty
294     * collection if the configuration is not defined.
295     *
296     * @param key The configuration key
297     * @return The configured values or an empty list if not defined
298     */
299    List<String> of(String key);
300
301    /**
302     * Return the list of values for the key returning the default values
303     * if the configuration is not defined.
304     *
305     * @param key The configuration key
306     * @return The configured values or default values
307     */
308    List<String> of(String key, String... defaultValues);
309
310    /**
311     * Return the list of integer values for the key returning an empty
312     * collection if the configuration is not defined.
313     *
314     * @param key The configuration key
315     * @return The configured values or an empty list if not defined
316     */
317    List<Integer> ofInt(String key);
318
319    /**
320     * Return the list of integer values for the key returning the default values
321     * if the configuration is not defined.
322     *
323     * @param key The configuration key
324     * @return The configured values or default values
325     */
326    List<Integer> ofInt(String key, int... defaultValues);
327
328    /**
329     * Return the list of long values for the key returning an empty
330     * collection if the configuration is not defined.
331     *
332     * @param key The configuration key
333     * @return The configured values or an empty list if not defined
334     */
335    List<Long> ofLong(String key);
336
337    /**
338     * Return the long values for the key returning the default values
339     * if the configuration is not defined.
340     *
341     * @param key The configuration key
342     * @return The configured values or default values
343     */
344    List<Long> ofLong(String key, long... defaultValues);
345  }
346
347
348  /**
349   * Return a Set of values configured.
350   *
351   * <h3>Example</h3>
352   * <pre>{@code
353   *
354   *  Set<String> operations = Config.getSet().of("my.operations", "put","delete");
355   *
356   * }</pre>
357   */
358  interface SetValue {
359
360    /**
361     * Return the Set of values for the key returning an empty
362     * collection if the configuration is not defined.
363     *
364     * @param key The configuration key
365     * @return The configured values or an empty Set if not defined
366     */
367    Set<String> of(String key);
368
369    /**
370     * Return the Set of values for the key returning the default values
371     * if the configuration is not defined.
372     *
373     * @param key The configuration key
374     * @return The configured values or default values
375     */
376    Set<String> of(String key, String... defaultValues);
377
378    /**
379     * Return the list of integer values for the key returning an empty
380     * collection if the configuration is not defined.
381     *
382     * @param key The configuration key
383     * @return The configured values or an empty list if not defined
384     */
385    Set<Integer> ofInt(String key);
386
387    /**
388     * Return the list of integer values for the key returning the default values
389     * if the configuration is not defined.
390     *
391     * @param key The configuration key
392     * @return The configured values or default values
393     */
394    Set<Integer> ofInt(String key, int... defaultValues);
395
396    /**
397     * Return the list of long values for the key returning an empty
398     * collection if the configuration is not defined.
399     *
400     * @param key The configuration key
401     * @return The configured values or an empty list if not defined
402     */
403    Set<Long> ofLong(String key);
404
405    /**
406     * Return the long values for the key returning the default values
407     * if the configuration is not defined.
408     *
409     * @param key The configuration key
410     * @return The configured values or default values
411     */
412    Set<Long> ofLong(String key, long... defaultValues);
413  }
414}