Hi all

basically this is a variant, but currently there is also the concept of a
PropertyProvider. I created this interface, because I wanted to make live
as easy as possible for the ones that implement a property source (aka
PropertyProvider). The functionality is very similar to what Spring has
(despite the fact that Spring uses abstract classes!). Property Providers
can very easily combined since there are only String keys/values to be
merged, compared etc. Once you have a new provider you can decorate it
again as a Configuration (by calling toConfiguration()).

I even also added a ConfigurationBuilder and I think having one is a good
thing. Basically for PropertyProviders I recommend to reduce the APIs
footprint for the common use cases. This is way the PropertyProviders
singleton exists: it reduces the implementation artifacts you have to
depend on for the most common uses cases as they are:

   - reading config from resources(files, uris/urls, classpath, ...)
   - creating a provider based on a map
   - combining providers (aggregation, intersection, subtraction etc.)

For all other use cases you typically will implement your own provider, or
we may provide prebuilt ones, e.g. for reading from a datasource, JSON
etc...
Summarizing

   - *Configuration *is the interface and the *representation *of a
   Configuration and the *accessor *for the current Configuration. It can
   be accessed directly, used as a base for injection, or as input to a
   template engine (the ladder two not yet covered).
   - *PropertyProvider *is the low *level building blocks *for getting
*configuration
   data *into the system. With a minimal API (or SPI) and a minimal
   footprint.
   - *PropertyProviders *is the singleton factory to access the most *common
   operations to build and combine of property providers*.
   - *ConfigurationBuilder *can be used to create a concrete configuration
   tree. But be aware for complex cases it might not work. E.g. think of a
   complex combined configuration tree with two or more subtrees and different
   combination strategies (not uncommon in complex scenarios). The builder
   gets very complex with different child builders. Similarly there are parts
   of config (providers) that may be instantiated and existing once, whereas
   other are even runtime dependent (e.g. on the current user logged
    authenticated)...

But overall I think Romain's idea go in the right direction ;)

Anatole



2014-12-01 18:53 GMT+01:00 Romain Manni-Bucau <[email protected]>:

> 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
> >
>



-- 
*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*

Reply via email to