@anatole: you know the issue with "it's modern" - esp. when it comes to naming (which is a matter of taste anyway)... so i would use whatever makes sense and not what's "modern" >currently<. if it's too bulky, people won't use it or introduce their own static helpers (once again...).
@romain: +1 regards, gerhard 2014-12-01 17:54 GMT+01:00 Romain Manni-Bucau <[email protected]>: > 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 > >> > > > > > > >> > > > > > >> > > > > >> > > > >> > > >> >
