config-caf/src/main/java/com/hpe/caf/api/CafConfigurationSource.java
private <T> T getCompleteConfig(final Class<T> configClass)
        throws ConfigurationException
    {
        T config = getConfig(configClass);
        for (final Field f : configClass.getDeclaredFields()) {
            if (f.isAnnotationPresent(Configuration.class)) {
                try {
                    Method setter = getMethod(f.getName(), configClass, PropertyDescriptor::getWriteMethod);
                    if (setter != null) {
                        setter.invoke(config, getCompleteConfig(f.getType()));
                    }
                } catch (final ConfigurationException e) {
                    LOG.debug("Didn't find any overriding configuration", e);
                } catch (final InvocationTargetException | IllegalAccessException e) {
                    incrementErrors();
                    throw new ConfigurationException("Failed to get complete configuration for " + configClass.getSimpleName(), e);
                }
            } else if (f.getType().equals(String.class) && f.isAnnotationPresent(Encrypted.class)) {
                try {
                    Method getter = getMethod(f.getName(), config.getClass(), PropertyDescriptor::getReadMethod);
                    Method setter = getMethod(f.getName(), config.getClass(), PropertyDescriptor::getWriteMethod);
                    if (getter != null && setter != null) {
                        final String configValue = (String) getter.invoke(config);
                        final String encryptedValue = isSubstitutorEnabled ? tokenSubstitutor(configValue) : configValue;
                        setter.invoke(config, getCipher().decrypt(encryptedValue));
                    }
                } catch (final CipherException | InvocationTargetException | IllegalAccessException e) {
                    throw new ConfigurationException("Failed to decrypt class fields", e);
                }
            } else if (isSubstitutorEnabled && f.getType().equals(String.class)) {
                try {
                    String propertyName = f.getName();
                    Method getter = getMethod(propertyName, config.getClass(), PropertyDescriptor::getReadMethod);
                    Method setter = getMethod(propertyName, config.getClass(), PropertyDescriptor::getWriteMethod);
                    if (getter != null && setter != null) {
                        // Property value may contain tokens that require substitution.
                        String propertyValueByToken = tokenSubstitutor((String) getter.invoke(config));
                        setter.invoke(config, propertyValueByToken);
                    }
                } catch (final InvocationTargetException | IllegalAccessException e) {
                    throw new ConfigurationException("Failed to get complete configuration for " + configClass.getSimpleName(), e);
                }
            }
        }
        return config;
    }
private <T> T getCompleteConfig(final Class<T> configClass)
        throws ConfigurationException
    {
        T config = getConfig(configClass);
        for (final Field f : configClass.getDeclaredFields()) {
            if (f.isAnnotationPresent(Configuration.class)) {
                try {
                    Method setter = getMethod(f.getName(), configClass, PropertyDescriptor::getWriteMethod);
                    if (setter != null) {
                        setter.invoke(config, getCompleteConfig(f.getType()));
                    }
                } catch (final ConfigurationException e) {
                    LOG.debug("Didn't find any overriding configuration", e);
                } catch (final InvocationTargetException | IllegalAccessException e) {
                    incrementErrors();
                    throw new ConfigurationException("Failed to get complete configuration for " + configClass.getSimpleName(), e);
                }
            } else if (f.getType().equals(String.class) && f.isAnnotationPresent(Encrypted.class)) {
                try {
                    Method getter = getMethod(f.getName(), config.getClass(), PropertyDescriptor::getReadMethod);
                    Method setter = getMethod(f.getName(), config.getClass(), PropertyDescriptor::getWriteMethod);
                    if (getter != null && setter != null) {
                        final String configValue = (String) getter.invoke(config);
                        final String encryptedValue = isSubstitutorEnabled ? tokenSubstitutor(configValue) : configValue;
                        setter.invoke(config, getCipher().decrypt(encryptedValue));
                    }
                } catch (final CipherException | InvocationTargetException | IllegalAccessException e) {
                    throw new ConfigurationException("Failed to decrypt class fields", e);
                }
            } else if (isSubstitutorEnabled && f.getType().equals(String.class)) {
                try {
                    String propertyName = f.getName();
                    Method getter = getMethod(propertyName, config.getClass(), PropertyDescriptor::getReadMethod);
                    Method setter = getMethod(propertyName, config.getClass(), PropertyDescriptor::getWriteMethod);
                    if (getter != null && setter != null) {
                        // Property value may contain tokens that require substitution.
                        String propertyValueByToken = tokenSubstitutor((String) getter.invoke(config));
                        setter.invoke(config, propertyValueByToken);
                    }
                } catch (final InvocationTargetException | IllegalAccessException e) {
                    throw new ConfigurationException("Failed to get complete configuration for " + configClass.getSimpleName(), e);
                }
            }
        }
        return config;
    }
private < T > T getCompleteConfig ( final Class < T > configClass ) throws ConfigurationException { T config = getConfig ( configClass ) ; for ( final Field f : configClass . getDeclaredFields ( ) ) { if ( f . isAnnotationPresent ( Configuration . class ) ) { try { Method setter = getMethod ( f . getName ( ) , configClass , PropertyDescriptor :: getWriteMethod ) ; if ( setter != null ) { setter . invoke ( config , getCompleteConfig ( f . getType ( ) ) ) ; } } catch ( final ConfigurationException e ) { LOG . debug ( "Didn't find any overriding configuration" , e ) ; } catch ( final InvocationTargetException | IllegalAccessException e ) { incrementErrors ( ) ; throw new ConfigurationException ( "Failed to get complete configuration for " + configClass . getSimpleName ( ) , e ) ; } } else if ( f . getType ( ) . equals ( String . class ) && f . isAnnotationPresent ( Encrypted . class ) ) { try { Method getter = getMethod ( f . getName ( ) , config . getClass ( ) , PropertyDescriptor :: getReadMethod ) ; Method setter = getMethod ( f . getName ( ) , config . getClass ( ) , PropertyDescriptor :: getWriteMethod ) ; if ( getter != null && setter != null ) { final String configValue = ( String ) getter . invoke ( config ) ; final String encryptedValue = isSubstitutorEnabled ? tokenSubstitutor ( configValue ) : configValue ; setter . invoke ( config , getCipher ( ) . decrypt ( encryptedValue ) ) ; } } catch ( final CipherException | InvocationTargetException | IllegalAccessException e ) { throw new ConfigurationException ( "Failed to decrypt class fields" , e ) ; } } else if ( isSubstitutorEnabled && f . getType ( ) . equals ( String . class ) ) { try { String propertyName = f . getName ( ) ; Method getter = getMethod ( propertyName , config . getClass ( ) , PropertyDescriptor :: getReadMethod ) ; Method setter = getMethod ( propertyName , config . getClass ( ) , PropertyDescriptor :: getWriteMethod ) ; if ( getter != null && setter != null ) { // Property value may contain tokens that require substitution. String propertyValueByToken = tokenSubstitutor ( ( String ) getter . invoke ( config ) ) ; setter . invoke ( config , propertyValueByToken ) ; } } catch ( final InvocationTargetException | IllegalAccessException e ) { throw new ConfigurationException ( "Failed to get complete configuration for " + configClass . getSimpleName ( ) , e ) ; } } } return config ; }
This is the recursive entry point for acquiring a complete configuration class to return. Attempt to acquire a deserialised object
representing the configuration class requested, and analyse it for declared fields marked @Configuration. If any are found, the
method recursively calls itself until all configuration is satisfied.

@param configClass the class representing configuration to acquire
@param <T> the class representing configuration to acquire
@return the completed (at this level) configuration
@throws ConfigurationException if configuration cannot be acquired
This is the recursive entry point for acquiring a complete configuration class to return . Attempt to acquire a deserialised object representing the configuration class requested and analyse it for declared fields marked @Configuration . If any are found the method recursively calls itself until all configuration is satisfied .