isnt it too complicated for most common use cases (+ not that lambda friendly cause of the 4 parameters which dont help writing readable code IMO).
Functionally it works but it makes default cases "hard" and actually you just want to implement the MapReduce pattern so maybe we should call it this way if we go this way. Romain Manni-Bucau @rmannibucau http://www.tomitribe.com http://rmannibucau.wordpress.com https://github.com/rmannibucau 2015-01-22 8:44 GMT+01:00 Anatole Tresch <[email protected]>: > 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
