Hi all

I would like to propose a small but effective change in the
ConfigurationContext SPI (the explanation why comes later in this email).
Currently
it is defined as:

*public interface *ConfigurationContext {

*void *addPropertySources(PropertySource... propertySourcesToAdd);
List<PropertySource> getPropertySources();
<T> *void *addPropertyConverter(TypeLiteral<T> typeToConvert,
PropertyConverter<T> propertyConverter);
<T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> type);
List<PropertyFilter> getPropertyFilters();
PropertyValueCombinationPolicy getPropertyValueCombinationPolicy();

}

My proposal is add an additional ConfigurationContextUpdates interface,
that allows to apply multiple changes to a ConfigurationContext and finally
apply the changes, once they are done. So the interface would be changed as
follows:

*public interface *ConfigurationContext {

List<PropertySource> getPropertySources();
<T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> type);
List<PropertyFilter> getPropertyFilters();
PropertyValueCombinationPolicy getPropertyValueCombinationPolicy();

// moved methods:
*// void *addPropertySources(PropertySource... propertySourcesToAdd);
// <T> *void *addPropertyConverter(TypeLiteral<T> typeToConvert,
//                              PropertyConverter<T> propertyConverter);
*ConfigurationContextUpdates startUpdate(); // new*

}

ConfigurationContextUpdates would be defined as follows:

*public interface *ConfigurationContextUpdates {

    ConfigurationContext getContext();

    *default *ConfigurationContextUpdates
addPropertySources(PropertySource... propertySourcesToAdd);
    ConfigurationContextUpdates
addPropertySources(Collection<PropertySource> propertySourcesToAdd);
    *default *ConfigurationContextUpdates
removePropertySources(PropertySource... propertySourcesToRemove);
    ConfigurationContextUpdates
removePropertySources(Collection<PropertySource> propertySourcesToRemove);
*    default *ConfigurationContextUpdates
removePropertySources(Predicate<PropertySource> selector);

    *default *ConfigurationContextUpdates
addPropertyFilters(PropertyFilter... filters);
    ConfigurationContextUpdates
addPropertyFilters(Collection<PropertyFilter> filters);
    *default *ConfigurationContextUpdates
removePropertyFilters(PropertyFilter... filters);
    *default *ConfigurationContextUpdates
removePropertyFilters(Predicate<PropertyFilter> selector);
    ConfigurationContextUpdates
removePropertyFilters(Collection<PropertyFilter> filters);


    <T> ConfigurationContextUpdates addPropertyConverter(TypeLiteral<T>
typeToConvert,

 PropertyConverter<T> propertyConverter);
    *default *ConfigurationContextUpdates
removePropertyConverters(PropertyConverter<?>... converters);
    ConfigurationContextUpdates
removePropertyConverters(Collection<PropertyConverter<?>> converters);

    ConfigurationContextUpdates
setPropertyValueCombinationPolicy(PropertyValueCombinationPolicy policy);

    /**
     * Apply all the changes to the underlying context.
     * @throws java.lang.IllegalStateException if the operation is called
multiple times, or another update was already
     * applied before.
     */
    *void *apply();
}

Now here are the reasons, why I think this makes sense:

   - it is much more easy to lock/synchronize the current state of a
   ConfigurationContext, since only for the time where the apply() is
   running special synchronization logi
   - a configuration context can not support being mutable at all by simply
   throwing a UnsupportedMethodException, when startUpdate() is called.
   - Changing a ConfigurationContext, e.g. for testing can now be as
   flexible as using CDIUnit for CDI. The regarding test support flexibility
   is easy to achieve.
   - *But most of all (and that was the reason, why I started to think on
   this enhancements), we can implement automatic configuration updates, e.g.
   based on new files added to a configuration directory or added to a
   database table, by implementing the mechanism as part of an "event" module.
   The event listener can determine from the change event the affected
   PropertySource, compare with the PropertySource already registered in the
   context(s) and remove/add/update new PropertySources as needed for the
   affected contexts. *This module currently is in development, and as soon
   as we would agree on this proposal I can add (and test it before), so we
   have an initial version for supporting configuration updates.

WDYT?

Anatole

Reply via email to