if you have tamaya in server/lib and call it from webapps for instance, each webapp can use different providers so you need different instances. That is no more a singleton. If it is still one cause we consider it as a factory/builder then the "instance" is useless no?
Romain Manni-Bucau @rmannibucau http://www.tomitribe.com http://rmannibucau.wordpress.com https://github.com/rmannibucau 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 >> >> >> >> >>
