JCache use ServiceLoader to get a Provider then you get a Manager and
finally a Cache. It is mainly to ensure you can "bulk" close what you
created I think. I'm not convinced we need it - maybe 1 level but no
more since we'll just kill "watcher" threads at the end of the
Configuration usage (AutoCloseable?).


About key conflict I saw isSameKey() or something like that in the API
but I really guess all this logic should be extracted in its own
interface (why I though starting with default methods were not a good
idea), maybe MergePolicy (with a good default doing nothing or
failing, not yet sure ;)).




Romain Manni-Bucau
@rmannibucau
http://www.tomitribe.com
http://rmannibucau.wordpress.com
https://github.com/rmannibucau


2014-12-01 19:15 GMT+01:00 Werner Keil <[email protected]>:
> 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
>>
>>

Reply via email to