3434import  java .lang .reflect .Array ;
3535import  java .util .Arrays ;
3636import  java .util .List ;
37+ import  java .util .Map ;
3738import  java .util .Optional ;
39+ import  java .util .function .Function ;
3840
3941import  org .eclipse .microprofile .config .spi .ConfigSource ;
4042import  org .eclipse .microprofile .config .spi .Converter ;
@@ -129,7 +131,9 @@ public interface Config {
129131     *             if the property cannot be converted to the specified type 
130132     * @throws java.util.NoSuchElementException 
131133     *             if the property is not defined or is defined as an empty string or the converter returns {@code null} 
134+      * @deprecated use {@link #get(String)} and {@link #as(Class)} instead 
132135     */ 
136+     @ Deprecated 
133137    <T > T  getValue (String  propertyName , Class <T > propertyType );
134138
135139    /** 
@@ -148,7 +152,9 @@ public interface Config {
148152     * @param propertyName 
149153     *            The configuration property name 
150154     * @return the resolved property value as a {@link ConfigValue} 
155+      * @deprecated use {@link #get(String)} and methods on the config node 
151156     */ 
157+     @ Deprecated 
152158    ConfigValue  getConfigValue (String  propertyName );
153159
154160    /** 
@@ -171,7 +177,9 @@ public interface Config {
171177     * @throws java.util.NoSuchElementException 
172178     *             if the property isn't present in the configuration or is defined as an empty string or the converter 
173179     *             returns {@code null} 
180+      * @deprecated use {@link #get(String)} and #asList(Class) 
174181     */ 
182+     @ Deprecated 
175183    default  <T > List <T > getValues (String  propertyName , Class <T > propertyType ) {
176184        @ SuppressWarnings ("unchecked" )
177185        Class <T []> arrayType  = (Class <T []>) Array .newInstance (propertyType , 0 ).getClass ();
@@ -198,7 +206,9 @@ default <T> List<T> getValues(String propertyName, Class<T> propertyType) {
198206     * 
199207     * @throws IllegalArgumentException 
200208     *             if the property cannot be converted to the specified type 
209+      * @deprecated use {@link #get(String)} and {@link #as(Class)} instead 
201210     */ 
211+     @ Deprecated 
202212    <T > Optional <T > getOptionalValue (String  propertyName , Class <T > propertyType );
203213
204214    /** 
@@ -219,7 +229,9 @@ default <T> List<T> getValues(String propertyName, Class<T> propertyType) {
219229     * 
220230     * @throws java.lang.IllegalArgumentException 
221231     *             if the property cannot be converted to the specified type 
232+      * @deprecated use {@link #get(String)} and #asList(Class) 
222233     */ 
234+     @ Deprecated 
223235    default  <T > Optional <List <T >> getOptionalValues (String  propertyName , Class <T > propertyType ) {
224236        @ SuppressWarnings ("unchecked" )
225237        Class <T []> arrayType  = (Class <T []>) Array .newInstance (propertyType , 0 ).getClass ();
@@ -257,7 +269,7 @@ default <T> Optional<List<T>> getOptionalValues(String propertyName, Class<T> pr
257269     * The returned sources will be sorted by descending ordinal value and name, which can be iterated in a thread-safe 
258270     * manner. The {@link java.lang.Iterable Iterable} contains a fixed number of {@linkplain ConfigSource configuration 
259271     * sources}, determined at application start time, and the config sources themselves may be static or dynamic. 
260-      *   
272+      * 
261273     * @return the configuration sources 
262274     */ 
263275    Iterable <ConfigSource > getConfigSources ();
@@ -291,4 +303,181 @@ default <T> Optional<List<T>> getOptionalValues(String propertyName, Class<T> pr
291303     *             If the current provider does not support unwrapping to the given type 
292304     */ 
293305    <T > T  unwrap (Class <T > type );
306+ 
307+     /* 
308+      * Tree handling methods 
309+      */ 
310+ 
311+     /** 
312+      * Fully qualified key of this config node (such as {@code server.port}). 
313+      * Returns an empty String for root config. 
314+      * 
315+      * @return key of this config 
316+      */ 
317+     String  key ();
318+ 
319+     /** 
320+      * Name of this node - the last element of a fully qualified key. 
321+      * <p> 
322+      * For example for key {@code server.port} this method would return {@code port}. 
323+      * 
324+      * @return name of this node 
325+      */ 
326+     String  name ();
327+ 
328+     /** 
329+      * Single sub-node for the specified name. 
330+      * For example if requested for key {@code server}, this method would return a config 
331+      * representing the {@code server} node, which would have for example a child {@code port}. 
332+      * 
333+      * @param name name of the nested node to retrieve 
334+      * @return sub node, never null 
335+      */ 
336+     Config  get (String  name );
337+ 
338+     /** 
339+      * A detached node removes prefixes of each sub-node of the current node. 
340+      * <p> 
341+      * Let's assume this node is {@code server} and contains {@code host} and {@code port}. 
342+      * The method {@link #key()} for {@code host} would return {@code server.host}. 
343+      * If we call a method {@link #key()} on a detached instance, it would return just {@code host}. 
344+      * 
345+      * @return a detached config instance 
346+      */ 
347+     Config  detach ();
348+ 
349+     /** 
350+      * Type of this node. 
351+      * 
352+      * @return type 
353+      */ 
354+     Type  type ();
355+ 
356+     /** 
357+      * Returns {@code true} if the node exists, whether an object, a list, or a 
358+      * value node. 
359+      * 
360+      * @return {@code true} if the node exists 
361+      */ 
362+     default  boolean  exists () {
363+         return  type () != Type .MISSING ;
364+     }
365+ 
366+     /** 
367+      * Returns {@code true} if this configuration node has a direct value. 
368+      * <p> 
369+      * Example (using properties files) for each node type: 
370+      * <p> 
371+      * {@link Type#OBJECT} - the node {@code server.tls} is an object node with direct value: 
372+      * <pre> 
373+      * # this is not recommended, yet it is possible: 
374+      * server.tls=true 
375+      * server.tls.version=1.2 
376+      * server.tls.keystore=abc.p12 
377+      * </pre> 
378+      * <p> 
379+      * {@link Type#LIST} - the node {@code server.ports} is a list node with direct value: 
380+      * TODO this may actually not be supported by the spec, as it can only be achieved through properties 
381+      * <pre> 
382+      * # this is not recommended, yet it is possible: 
383+      * server.ports=8080 
384+      * server.ports.0=8081 
385+      * server.ports.1=8082 
386+      * </pre> 
387+      * <p> 
388+      * {@link Type#VALUE} - the nodes {@code server.port} and {@code server.host} are values 
389+      * <pre> 
390+      * server.port=8080 
391+      * server.host=localhost 
392+      * </pre> 
393+      * 
394+      * @return {@code true} if the node has direct value, {@code false} otherwise. 
395+      */ 
396+     boolean  hasValue ();
397+ 
398+     /** 
399+      * Typed value created using a converter function. 
400+      * The converter is called only if this config node exists. 
401+      * 
402+      * @param converter to create an instance from config node 
403+      * @param <T> type of the object 
404+      * @return converted value of this node, or an empty optional if this node does not exist 
405+      * @throws java.lang.IllegalArgumentException if this config node cannot be converted to the desired type 
406+      */ 
407+     <T > Optional <T > as (Function <Config , T > converter );
408+ 
409+     /** 
410+      * Typed value created using a configured converter. 
411+      * 
412+      * @param type class to convert to 
413+      * @param <T> type of the object 
414+      * @return converted value of this node, or empty optional if this node does not exist 
415+      * @throws java.lang.IllegalArgumentException if this config node cannot be converted to the desired type 
416+      */ 
417+     <T > Optional <T > as (Class <T > type );
418+ 
419+     /** 
420+      * Map to a list of typed values. 
421+      * This method is only available if the current node is a {@link org.eclipse.microprofile.config.Config.Type#LIST} 
422+      * or if it has a direct value. In case a direct value of type String exists, it expects comma separated elements. 
423+      * 
424+      * @param type class to convert each element to 
425+      * @param <T> type of the object 
426+      * @return list of typed values 
427+      * @throws java.lang.IllegalArgumentException if this config node cannot be converted to the desired type 
428+      */ 
429+     <T > Optional <List <T >> asList (Class <T > type );
430+ 
431+     /** 
432+      * Contains the (known) config values as a map of key->value pairs. 
433+      * 
434+      * @return map of sub keys of this config node, or empty if this node does not exist 
435+      */ 
436+     Optional <Map <String , String >> asMap ();
437+ 
438+     /** 
439+      * A list of child nodes. 
440+      * In case this node is {@link org.eclipse.microprofile.config.Config.Type#LIST} returns the list in the correct order. 
441+      * In case this node is {@link org.eclipse.microprofile.config.Config.Type#OBJECT} returns all direct child nodes 
442+      *      (in an unknown order) 
443+      * 
444+      * @return list of child nodes, or empty if this node does not exist 
445+      */ 
446+     Optional <List <Config >> asNodeList ();
447+ 
448+     /* 
449+      * Shortcut helper methods 
450+      */ 
451+     default  Optional <String > asString () {
452+         return  as (String .class );
453+     }
454+ 
455+     default  Optional <Integer > asInt () {
456+         return  as (Integer .class );
457+     }
458+ 
459+     /** 
460+      * Config node type. 
461+      */ 
462+     enum  Type  {
463+         /** 
464+          * Object node with named members and a possible direct value. 
465+          */ 
466+         OBJECT ,
467+         /** 
468+          * List node with a list of indexed parameters. 
469+          * Note that a list node can also be accessed as an object node - child elements 
470+          * have indexed keys starting from {@code 0}. 
471+          * List nodes may also have a direct value. 
472+          */ 
473+         LIST ,
474+         /** 
475+          * Value node is a leaf node - it does not have any child nodes, only direct value. 
476+          */ 
477+         VALUE ,
478+         /** 
479+          * Node is missing, it will return only empty values. 
480+          */ 
481+         MISSING 
482+     }
294483}
0 commit comments