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