Haven't looked into it in so much detail, but what I saw from the JCache JSR it also defines just a single service interface in SPI which then gets applied via the usual Java Service Provider mechanism.
JSR 363 leaves it a bit more flexible (as ME 8 knows a slight variation of that via LIBlets and some implementations may prefer OSGi over JDK Service Loaders;-) but in essence the SPI package defines some similar interfaces. Werner On Mon, Dec 1, 2014 at 7:09 PM, Oliver B. Fischer <[email protected]> wrote: > I like the idea of builders. > > If we have default providers via SPI how do we handle the a case there two > providers offer a value for the same key? > > Furthermore I would like to have the posibillty to decide which providers > are automatically choosen by providing a -Dproviders=org.apache.tamaya. > ProviderA,org.apache.tamaya.ProviderB > > Oliver > > Am 01.12.14 18:53, schrieb Romain Manni-Bucau: > > Markdown4j has something pretty nice (specific but I guess the idea is >> reusable for us): >> >> Configuration.builder().forceExtentedProfile().registerPlugins(new >> YumlPlugin(), new WebSequencePlugin(), new >> IncludePlugin()).convertNewline2Br().setDecorator(decorator). >> setCodeBlockEmitter(new >> CodeBlockEmitter()).build(). >> >> What I like: >> 1) builder (so can be read-only once built + API is auto-documented >> and here it is fluent) >> 2) manual registration of plugins (loaders for us) >> >> So we could get: >> >> Configuration c = new Configuration.Builder().propertyProviders(new >> MyProviders1(), new MyProviders2()).build() >> >> Not that we can easily write a PropertyProviders using a SPI and I >> would wire it as a default one if propertyProviders is not called (ie >> set of providers is empty. >> >> This would also allow us to add other features later like property >> post processors (to change properties loaded from providers etc...) >> pretty easily and clean-ly. >> >> wdyt? >> >> >> >> Romain Manni-Bucau >> @rmannibucau >> http://www.tomitribe.com >> http://rmannibucau.wordpress.com >> https://github.com/rmannibucau >> >> >> 2014-12-01 18:31 GMT+01:00 Oliver B. Fischer <[email protected]>: >> >>> Hi, >>> >>> for me the most simple use case is >>> >>> Configuration conf = new Configuration(); >>> String value = conf.get("key") >>> >>> And this use case is already very complex under the hood. >>> >>> Before discussing other details we have to decide how PropertyProviders >>> are >>> activated. >>> >>> I would like to have the following possibilites: >>> >>> 1. Tamaya activates all PropertyProviders found in the classpath and >>> activated via SPI. >>> 2. Tamaya activates only a explicitly named list of Property providers >>> 3. I have the ability to control the order in which the property solution >>> will be performed >>> >>> Bye, >>> >>> Oliver >>> >>> >>> Am 01.12.14 17:54, schrieb Romain Manni-Bucau: >>> >>> Configuration.current() sounds easier to understand first time you see >>>> it. I like Configuration.newInstance() if that's really what it does >>>> (ie no caching by classloader or anything else). >>>> >>>> >>>> Romain Manni-Bucau >>>> @rmannibucau >>>> http://www.tomitribe.com >>>> http://rmannibucau.wordpress.com >>>> https://github.com/rmannibucau >>>> >>>> >>>> 2014-12-01 17:42 GMT+01:00 Anatole Tresch <[email protected]>: >>>> >>>>> There is a naming concept from Stephen Colebourne when to use of, from, >>>>> with. I try to lookup the link later, see also jsr 310 and 354. >>>>> getInstance, valueOf are considered to be outdated for modern api >>>>> design. >>>>> >>>>> Adding a helper, why? Another artifact a user must know, makes sense, >>>>> where >>>>> you have a huge acces api IMO (see PropertyProviders where the factory >>>>> methods are not part of the PropertyProvider interface. For >>>>> Configuration >>>>> I >>>>> prefer having sn intuitive simple/single access... >>>>> >>>>> Nevertheless I would like to encourage you to make a concrete proposal >>>>> how >>>>> would name things, so we can compare what your idea of fluent is ;) >>>>> >>>>> -anatole >>>>> Gerhard Petracek <[email protected]> schrieb am Mo., 1. Dez. >>>>> 2014 >>>>> um 17:24: >>>>> >>>>> hi anatole, >>>>>> >>>>>> again - yes and no. >>>>>> no - it wasn't similar before, because you haven't started with the >>>>>> most >>>>>> trivial usage (supported by tamaya right now). >>>>>> however, now we are talking about a "different part" of the api which >>>>>> is >>>>>> very similar -> yes >>>>>> >>>>>> -> let's discuss >>>>>> String myValue = Configuration.of().get("myKey").orElse(null); >>>>>> >>>>>> maybe we can get something better than ".of().get" or we provide a >>>>>> static >>>>>> helper for it. >>>>>> currently this first part doesn't read fluently. a lot of users might >>>>>> not >>>>>> need more than that (at least in the beginning) and therefore it >>>>>> should >>>>>> be >>>>>> nice. >>>>>> >>>>>> regards, >>>>>> gerhard >>>>>> >>>>>> >>>>>> >>>>>> 2014-12-01 16:07 GMT+01:00 Tresch, Anatole >>>>>> <anatole.tresch@credit-suisse. >>>>>> com >>>>>> >>>>>>> : >>>>>>> Hi Gerhard >>>>>>> >>>>>>> as I said granularity is not matching in your example. Comparing >>>>>>> concepts >>>>>>> on the same granularity level it would be: >>>>>>> >>>>>>> String myValue = ConfigResolver.getPropertyValue("myKey"); >>>>>>> // >>>>>>> Deltaspike >>>>>>> >>>>>>> compared to: >>>>>>> >>>>>>> String myValue = Configuration.of().get("myKey").orElse(null); >>>>>>> // >>>>>>> Tamaya >>>>>>> >>>>>>> So that looks more or less similar (I did not count the characters) >>>>>>> ;) >>>>>>> >>>>>>> It will be interesting to see how it feels, when defining the model >>>>>>> >>>>>> behind >>>>>> >>>>>>> this facades. Tamaya can support dynamic property providers (aka >>>>>>> PropertySource) managed by CDI for app config as well. But on top of >>>>>>> them >>>>>>> also will probably be capable to configure CDI and other aspects. >>>>>>> Already >>>>>>> in place is a Properties implementation that can be applied to >>>>>>> System.setProperties(Properties), which adds dynamic >>>>>>> >>>>>> (configurable)system >>>>>> >>>>>>> properties as a minimal shared level of API already available as of >>>>>>> now >>>>>>> >>>>>> on >>>>>> >>>>>>> SE level. >>>>>>> >>>>>>> -Anatole >>>>>>> >>>>>>> >>>>>>> -----Original Message----- >>>>>>> From: Gerhard Petracek [mailto:[email protected]] >>>>>>> Sent: Montag, 1. Dezember 2014 14:30 >>>>>>> To: [email protected] >>>>>>> Subject: Re: Use Case 1: Read simple properties and get values. >>>>>>> >>>>>>> hi anatole, >>>>>>> >>>>>>> yes and no - the part i talked about mainly is: >>>>>>> String myValue = ConfigResolver.getPropertyValue("myKey"); >>>>>>> >>>>>>> compared to: >>>>>>> Configuration config = PropertyProviders.fromPaths(/*...*/); >>>>>>> String myValue = config.get("myKey", String.class); >>>>>>> >>>>>>> regards, >>>>>>> gerhard >>>>>>> >>>>>>> >>>>>>> >>>>>>> 2014-12-01 14:22 GMT+01:00 Anatole Tresch <[email protected]>: >>>>>>> >>>>>>> Hi Gerhard >>>>>>>> What you describe is use case that will follow later. You asked me >>>>>>>> to >>>>>>>> >>>>>>> start >>>>>>> >>>>>>>> with a simple one, so this is the most simple one. Next use cases >>>>>>>> will >>>>>>>> >>>>>>> add >>>>>>> >>>>>>>> aadditional sources, then we will combine things (aka complex >>>>>>>> >>>>>>> overridings). >>>>>>> >>>>>>>> After that we will emphasize on the environment model, because this >>>>>>>> >>>>>>> defines >>>>>>> >>>>>>>> the context, which determines which config is appropriate. The user >>>>>>>> in >>>>>>>> >>>>>>> most >>>>>>> >>>>>>>> cases will call Configuration.of() to access.the current >>>>>>>> configuration. >>>>>>>> This method then is backed by a config provider. This provider >>>>>>>> decides >>>>>>>> >>>>>>> how >>>>>>> >>>>>>>> the current environment is determining the config to be returned >>>>>>>> (aka >>>>>>>> defines implements the config metamodel). >>>>>>>> This metamodel can be defined rather differently depending your >>>>>>>> target >>>>>>>> runtime and require config solutions. And for this we require the >>>>>>>> >>>>>>> basics >>>>>> >>>>>>> (where I started). >>>>>>>> >>>>>>>> What is in Deltaspike as of now is only a subset of what I see >>>>>>>> >>>>>>> necessary >>>>>> >>>>>>> to >>>>>>> >>>>>>>> build a compelling config system. We will be able to cover that >>>>>>>> functionality easily and it will be easy to use. >>>>>>>> >>>>>>>> So please have some patience and let me post the use cases and >>>>>>>> >>>>>>> solutions >>>>>> >>>>>>> one by one and focus on these. I try to post them if possible on a >>>>>>>> >>>>>>> daily >>>>>> >>>>>>> basis. Hopefully we will have then a common terminology and >>>>>>>> >>>>>>> architectural >>>>>> >>>>>>> view on the whole topic that helps us discuss things efficiently ;) >>>>>>>> >>>>>>>> Cheers >>>>>>>> Anatole >>>>>>>> >>>>>>>> Gerhard Petracek <[email protected]> schrieb am Mo., 1. >>>>>>>> Dez. >>>>>>>> >>>>>>> 2014 >>>>>>> >>>>>>>> um 13:58: >>>>>>>> >>>>>>>> hi @ all, >>>>>>>>> >>>>>>>>> @anatole: thx for starting this thread. >>>>>>>>> >>>>>>>>> let's start/continue with the first part - the equivalent in >>>>>>>>> >>>>>>>> deltaspike >>>>>> >>>>>>> is: >>>>>>>> >>>>>>>>> String myValue = ConfigResolver.getPropertyValue("myKey"); >>>>>>>>> >>>>>>>>> as a precondition for this call, you need 1-n registered >>>>>>>>> >>>>>>>> config-source(s) >>>>>>> >>>>>>>> (= std. spi config -> in this case in: >>>>>>>>> META-INF/services/org.apache.deltaspike.core.spi.config. >>>>>>>>> >>>>>>>> ConfigSource). >>>>>> >>>>>>> this approach is nice for >applications<, because everything is done >>>>>>>>> automatically based on the "visible" configs. >>>>>>>>> furthermore, it's very flexible, because a config-source >>>>>>>>> encapsulates >>>>>>>>> >>>>>>>> the >>>>>>> >>>>>>>> logic for different config-locations (files, jndi, db,...). >>>>>>>>> >>>>>>>>> mark wrote that part -> he might add some details which are >>>>>>>>> important >>>>>>>>> >>>>>>>> to >>>>>>> >>>>>>>> him (for the >current< use-case): >>>>>>>>> >>>>>>>>> regards, >>>>>>>>> gerhard >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> 2014-12-01 11:30 GMT+01:00 Romain Manni-Bucau < >>>>>>>>> [email protected] >>>>>>>>> >>>>>>>> : >>>>>>> >>>>>>>> Looks like a good entry point, I like the "prefixing" to switch of >>>>>>>>>> "reader". However I don't like to be forced to use an Optional. In >>>>>>>>>> several cases I prefer to stick to properties API ie get something >>>>>>>>>> >>>>>>>>> or >>>>>> >>>>>>> a default, default being null if not set when queried. Optional is >>>>>>>>>> >>>>>>>>> not >>>>>>> >>>>>>>> bad but makes code very verbose for pretty much nothing is several >>>>>>>>>> cases (of config). >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> wdyt? >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> Romain Manni-Bucau >>>>>>>>>> @rmannibucau >>>>>>>>>> http://www.tomitribe.com >>>>>>>>>> http://rmannibucau.wordpress.com >>>>>>>>>> https://github.com/rmannibucau >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> 2014-12-01 11:15 GMT+01:00 Anatole Tresch <[email protected]>: >>>>>>>>>> >>>>>>>>>>> Hi all >>>>>>>>>>> >>>>>>>>>>> I have put together a first couple of simple use cases. It is >>>>>>>>>>> >>>>>>>>>> targeting >>>>>>>> >>>>>>>>> SE >>>>>>>>>> >>>>>>>>>>> level only (as many use cases will do, especially the basic >>>>>>>>>>> >>>>>>>>>> ones). >>>>>> >>>>>>> *Basic use case 1:* >>>>>>>>>>> We want to write some properties file and read it from a file or >>>>>>>>>>> >>>>>>>>>> the >>>>>>> >>>>>>>> classpath into a Configuration instance. This is done by >>>>>>>>>>> >>>>>>>>>>> Configuration config = PropertyProviders.fromPaths( >>>>>>>>>>> >>>>>>>>>>> "classpath:ucs/UC1ReadProperties/UC1ReadPropertiesTest. >>>>>>>> properties") >>>>>>>> >>>>>>>>> .toConfiguration(); >>>>>>>>>>> >>>>>>>>>>> The PropertyProvider which is created here by >>>>>>>>>>> PropertyProviders.fromPaths hereby >>>>>>>>>>> is a simplified version that can be easily aggregated (for >>>>>>>>>>> >>>>>>>>>> composites) >>>>>>>> >>>>>>>>> and >>>>>>>>>> >>>>>>>>>>> only provides String values (no type support yet). Nevertheless >>>>>>>>>>> mapping to Configuration >>>>>>>>>>> is trivial. >>>>>>>>>>> >>>>>>>>>>> Given that we then can access different values. Since we return >>>>>>>>>>> >>>>>>>>>> Optional >>>>>>>>> >>>>>>>>>> as >>>>>>>>>> >>>>>>>>>>> a result type the values returned are never null. For showing the >>>>>>>>>>> capabilities I added multiple examples of types: >>>>>>>>>>> >>>>>>>>>>> String name = config.get("name").orElse("Anatole"); >>>>>>>>>>> BigDecimal bigNum = config.get("num.BD", BigDecimal.class) >>>>>>>>>>> .orElseThrow(() -> new >>>>>>>>>>> IllegalStateException("Sorry")); >>>>>>>>>>> double anotherNum = config.getDouble("num.Double") >>>>>>>>>>> >>>>>>>>>> .getAsDouble(); >>>>>> >>>>>>> long longNum = config.getLong("num.Long").orElse(288900L); >>>>>>>>>>> >>>>>>>>>>> Finally plugins or modules often only want a view on their subset >>>>>>>>>>> >>>>>>>>>> of >>>>>>> >>>>>>>> entries. This can be achieved easily by using >>>>>>>>>>> >>>>>>>>>>> Configuration areaConfig2 = >>>>>>>>>>> >>>>>>>>>> config.with(ConfigFunctions.selectArea("num")); >>>>>>>>>> >>>>>>>>>>> This will return a Configuration subset, which will only contain >>>>>>>>>>> >>>>>>>>>> the >>>>>>> >>>>>>>> child >>>>>>>>>> >>>>>>>>>>> values of the num area, which are BD, double, ... ConfigFunctions >>>>>>>>>>> >>>>>>>>>> BTW >>>>>>> >>>>>>>> is >>>>>>>>> >>>>>>>>>> a >>>>>>>>>> >>>>>>>>>>> dingleton accessot, which serves >>>>>>>>>>> ConfigOperator functional extensions (there is also a >>>>>>>>>>> >>>>>>>>>> ConfigQuery), >>>>>> >>>>>>> so >>>>>>>> >>>>>>>>> this >>>>>>>>>> >>>>>>>>>>> is a common pattern for adding whatever extension needed to >>>>>>>>>>> Configuration instances >>>>>>>>>>> without having them to directly implement/provide on >>>>>>>>>>> >>>>>>>>>> Configuration >>>>>> >>>>>>> itself. >>>>>>>>>> >>>>>>>>>>> All the features are reflected in the test class (in the core >>>>>>>>>>> >>>>>>>>>> module): >>>>>>>> >>>>>>>>> org.apache.tamaya.uc.UC1ReadProperties.UC1ReadPropertiesTest (we >>>>>>>>>>> >>>>>>>>>> should >>>>>>>>> >>>>>>>>>> lower case the package name ;) ). >>>>>>>>>>> >>>>>>>>>>> This test also contains additional features/use cases... >>>>>>>>>>> >>>>>>>>>>> *Extended use case 1.1: multiple formats* >>>>>>>>>>> It is possible to read multiple file formats, by default the >>>>>>>>>>> >>>>>>>>>> following >>>>>>>> >>>>>>>>> formats are supported >>>>>>>>>>> >>>>>>>>>>> - .properties (as defined by java.util.Properties) >>>>>>>>>>> - .xml properties (as defined by java.util.Properties) >>>>>>>>>>> - .ini format >>>>>>>>>>> >>>>>>>>>>> Configuration config = PropertyProviders.fromPaths( >>>>>>>>>>> >>>>>>>>>>> "classpath:ucs/UC1ReadProperties/UC1ReadPropertiesTest. >>>>>>>> properties", >>>>>>>> >>>>>>>>> "classpath:ucs/UC1ReadProperties/UC1ReadPropertiesTest.xml", >>>>>>>>>>> "file:c:/temp/myProps.properties") >>>>>>>>>>> .toConfiguration(); >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> In the back format resolution is handled by an SPI, which is >>>>>>>>>>> extendable/pluggable. >>>>>>>>>>> The basic component here ist the ConfigurationFormats singleton >>>>>>>>>>> >>>>>>>>>> and >>>>>> >>>>>>> the ConfigurationFormat >>>>>>>>>>> interfaCE. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> *Extended use case 1.2: multiple sources* >>>>>>>>>>> It is possible to read multiple files, by adding >>>>>>>>>>> >>>>>>>>>>> - additional paths (see above) >>>>>>>>>>> - ant styled expressions >>>>>>>>>>> >>>>>>>>>>> Configuration config = PropertyProviders.fromPaths( >>>>>>>>>>> "classpath:ucs/UC1ReadProperties/UC1ReadPropertiesTest.*", >>>>>>>>>>> "classpath*:ucs/UC1ReadProperties/**/*.properties") >>>>>>>>>>> .toConfiguration(); >>>>>>>>>>> >>>>>>>>>>> In the back resource resolution is handled by an SPI, which is >>>>>>>>>>> extendable/pluggable as well. file,file*,classpath,classpath* >>>>>>>>>>> >>>>>>>>>> are >>>>>> >>>>>>> the >>>>>>> >>>>>>>> locator ids which are implemented based on a subset of the >>>>>>>>>>> >>>>>>>>>> Spring >>>>>> >>>>>>> resource >>>>>>>>>> >>>>>>>>>>> loader is working. Additional resource location mechanism could >>>>>>>>>>> >>>>>>>>>> be >>>>>> >>>>>>> easily added by implementing the >>>>>>>>>>> org.apache.tamaya.core.internal.resources.PathResolver >>>>>>>>>>> >>>>>>>>>> interface. >>>>>> >>>>>>> If >>>>>>> >>>>>>>> one >>>>>>>>> >>>>>>>>>> implements and registers (using the Bootstrap component, by >>>>>>>>>>> >>>>>>>>>> default >>>>>> >>>>>>> using >>>>>>>>> >>>>>>>>>> ServiceLoader), e.g. a resolver called "foo", the expression >>>>>>>>>>> >>>>>>>>>> would >>>>>> >>>>>>> look >>>>>>>> >>>>>>>>> like: >>>>>>>>>>> >>>>>>>>>>> Configuration config = PropertyProviders.fromPaths( >>>>>>>>>>> "foo:myResourceExpression"); >>>>>>>>>>> >>>>>>>>>>> Next variants would be reading properties from other resources. >>>>>>>>>>> >>>>>>>>>> We >>>>>> >>>>>>> could >>>>>>>>> >>>>>>>>>> e.g. create a programmatic random resource and also use a >>>>>>>>>>> >>>>>>>>>> database, >>>>>> >>>>>>> or >>>>>>>> >>>>>>>>> remote resource. >>>>>>>>>>> >>>>>>>>>>> Cheers, >>>>>>>>>>> Anatole >>>>>>>>>>> >>>>>>>>>>> -- >>> N Oliver B. Fischer >>> A Schönhauser Allee 64, 10437 Berlin, Deutschland/Germany >>> P +49 30 44793251 >>> M +49 178 7903538 >>> E [email protected] >>> S oliver.b.fischer >>> J [email protected] >>> X http://xing.to/obf >>> >>> > -- > N Oliver B. Fischer > A Schönhauser Allee 64, 10437 Berlin, Deutschland/Germany > P +49 30 44793251 > M +49 178 7903538 > E [email protected] > S oliver.b.fischer > J [email protected] > X http://xing.to/obf > >
