YES! As I said this would be a topic for later IMO. Looking at the discussions so far I would call it* Environment.current() *(instead of of() ). For getting configuration right you must have an environment model in place that is very flexible (basically I tend to say modelling and implementing the environment provider is more complex, than assembling the configuration that is relevant to that environment)...
2014-12-01 19:20 GMT+01:00 Werner Keil <[email protected]>: > If you get one by app, is there any form of "context" you'd pass to such > factory method? > > Currency.getInstance() returns exactly one singleton instance of a Currency > class (otherwise has no constructor either) for a given currency code. > While Money.of() in JSR 354 RI returns totally different instances > depending on the combination of (nearly unlimited) different numbers and > currency codes. 354 tries to broaden the definition of Currency, but if you > get exactly one distinct instance per VM/app that's a singleton IMHO even > if you may call the same application multiple times. > > On Mon, Dec 1, 2014 at 7:12 PM, Romain Manni-Bucau <[email protected]> > wrote: > > > Hmm, > > > > for me getInstance() = singleton in term of instance where > > Configuration will be all but a singleton IMO (you'll get at least one > > by app and surely a new instance each time you call it) no? > > > > > > Romain Manni-Bucau > > @rmannibucau > > http://www.tomitribe.com > > http://rmannibucau.wordpress.com > > https://github.com/rmannibucau > > > > > > 2014-12-01 18:56 GMT+01:00 Werner Keil <[email protected]>: > > > Hi, > > > > > > Adding to the question of convenience factories, there is no such thing > > as > > > "naming convention" by Stephen Colebourne or JSR 310. In fact, it > > violates > > > or bends almost every one of them in itself, so a suggestion like > > > Configuration.current() would sound very similar to the > > LocalDateTime.now() > > > ones in 310. > > > For several other cases of() or longer variations (like ofMilli() > > ofNanos() > > > etc.;-O) are used, while static factories from strings similar to what > > JSR > > > 354 adopted are called parse(String). > > > > > > Josh Bloch defined a clear distinction between what he then in most > cases > > > (except EnumSet, that's where he started using of() so Josh also > > "invented" > > > that while it violated some of his earlier naming conventions;-D) > called > > > valueOf() and getInstance(), see > > > > > > http://blog.codefront.net/2003/06/21/java-tip-2-static-factory-methods-vs-constructors/ > > > getInstance() returns a singleton, either the only instance for this > type > > > of object or the only instance for a distinct code or enum (see > > > java.util.Currency) > > > > > > Very recent APIs and JSRs like MEEP 8 make a clear distinction, and > > classes > > > like > > > > > > https://docs.oracle.com/javame/8.0/api/meep/api/javax/microedition/event/EventManager.html > > > clearly explain that, too. In other places ME 8 uses of() where > > appropriate. > > > So at least getInstance() is neither outdated nor wrong, it just > depends > > on > > > what you return. > > > > > > If Configuration returns just a default instance then > > > Configuration.getInstance() seems appropriate. > > > > > > > > > Werner Keil | JCP Executive Committee Member, JSR 363 Co Spec Lead | > > > Eclipse UOMo Lead, Babel Language Champion | Apache Committer > > > > > > Twitter @wernerkeil | @UnitAPI | @JSR354 | @DeviceMap | #EclipseUOMo | > > > #Java_Social > > > | #DevOps > > > Skype werner.keil | Google+ gplus.to/wernerkeil > > > > > > On Mon, Dec 1, 2014 at 6:31 PM, Oliver B. Fischer < > > [email protected]> > > > wrote: > > > > > >> 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 > > >> > > >> > > > -- *Anatole Tresch* Java Engineer & Architect, JSR Spec Lead Glärnischweg 10 CH - 8620 Wetzikon *Switzerland, Europe Zurich, GMT+1* *Twitter: @atsticks* *Blogs: **http://javaremarkables.blogspot.ch/ <http://javaremarkables.blogspot.ch/>* *Google: atsticksMobile +41-76 344 62 79*
