Dear all

*let's think about additional use cases:*
1) as mentioned in my last mail about collection types,* overriding may not
always be the right resolution policy *for accessing a configured value
(e.g. for collecting all configured values in a final set/list).
2) sometimes I want to define my own PropertyConverters (already
implemented)
3) sometimes I even would like to evaluate multiple keys taking the result
of the first property key that returns a config property (nice convenience)

When we will add all this kind of aspect into Configuration, we will end up
in a messy interface, e.g. for
String get(String);
<T> T get(String, Class<T>);
<T> T get(String, Class<T>, PropertyConverter);

String get(String, ValueCollector);
<T> T get(String, Class<T>, ValueCollector);
<T> T get(String, Class<T>, PropertyConverter, ValueCollector);
...

Obviously that does not make sense.

Instead of I would propose, we would define a PropertyQuery, which
basically is

   - is the same as a TypeLiteral<T> solving the type aspects
   - has a list of *keys* to be evaluated, at least one
   - optionally has a ValueCollector
   - optionally has a list of PropertyConverter

With that our interface gets much leaner, but still flexible enough to
accommodate the use cases above:

String get(String);
<T> T get(String, Class<T>);
<T> T get(String, Class<T>, PropertyConverter); // may be ommitted as well ?
<T> get(PropertyQuery<T> query);
...

This solves all use cases above and gives us an easy way to add additional
feature, if needed (I dont see any, but who knows). Hereby ValueCollector
would be defined as follows:

@FunctionalInterface
public interface ValueCollector {

    /**
     * Method that is called for each value returned by a PropertySource
for the given key.
     * @param currentValue the current value, including null.
     *                     The collector should either combine the existing
value with value from {@code currentValue}
     *                     or replace the value in {@code currentValue}
with {@code valueRead}, hereby returning the
     *                     result to be used as new {@code currentValue}.
     * @param key The current key to be evaluated.
     * @param newValue the new value read from the current {@code
propertySource}, not null.
     * @param propertySource The PropertySource that returned the current
value (either as the result of a direct
     *                       access of as a property Map containing the
given key. The PropertySource given
     *                       may be evaluated for additional meta-data, how
the given values are to be combined.
     * @return the value to be used for future evaluation.
     */
    String collect(String key, String newValue, PropertySource
propertySource,
                   String currentValue);

    /**
     * Default overriding collector.
     */
    public final ValueCollector DEFAULT_OVERRIDING_COLLECTOR = (k, nv, ps,
cv) -> nv;
}

Feedback?

Cheers,
Anatole

Reply via email to