You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tamaya.apache.org by an...@apache.org on 2015/01/04 02:50:45 UTC

[1/4] incubator-tamaya git commit: TAMAYA-42, 43, 44: Checkstyle fixes.

Repository: incubator-tamaya
Updated Branches:
  refs/heads/master 59a9e2110 -> 7272198b6


TAMAYA-42,43,44: Checkstyle fixes.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/66759b53
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/66759b53
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/66759b53

Branch: refs/heads/master
Commit: 66759b5332b0e0387cfc89e413dc847122c334de
Parents: cc237eb
Author: anatole <an...@apache.org>
Authored: Sun Jan 4 02:21:47 2015 +0100
Committer: anatole <an...@apache.org>
Committed: Sun Jan 4 02:26:23 2015 +0100

----------------------------------------------------------------------
 core/src/main/java/org/apache/tamaya/core/resources/Resource.java   | 1 -
 .../main/java/org/apache/tamaya/core/resources/ResourceLoader.java  | 1 -
 2 files changed, 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/66759b53/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/resources/Resource.java b/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
index 31c679d..7e17d1b 100644
--- a/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
+++ b/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
@@ -22,7 +22,6 @@ import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URI;
-import java.net.URL;
 import java.util.Objects;
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/66759b53/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java b/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
index 5aff10a..0f33201 100644
--- a/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
+++ b/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
@@ -20,7 +20,6 @@ package org.apache.tamaya.core.resources;
 
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.List;
 
 /**
  * Interface to be implemented by modules. By default only direct file/resource resolution is supported, whereas


Re: [2/4] incubator-tamaya git commit: TAMAYA-42, 43, 44: Readded non Spring related parts. Simplified resource API. Readded other tests.

Posted by Anatole Tresch <at...@gmail.com>.
;) i will now be offline for a couple of hours (driving my family home from
holidays)..

Anatole
Mark Struberg <st...@yahoo.de> schrieb am So., 4. Jan. 2015 um 13:33:

> Ok I get it now. Some BasePropertySource which might be reused in
> 'userland' code for easily adding yet another ConfigSource which is
> behaviourially very close to what the will end up in core (for some default
> locations).
> We still need to discuss how those 'default' PropertySources should behave
> though.
>
> LieGrue,
> strub
>
>
>
>
> On Sunday, 4 January 2015, 12:39, Romain Manni-Bucau <
> rmannibucau@gmail.com> wrote:
> >
> >In extensions for sure but url constructor as a common practise
> >Le 4 janv. 2015 11:42, "Mark Struberg" <st...@yahoo.de> a écrit :
> >
> >> why we should have these deps in the API module.
> >>
> >>
> >>I just wanted to hear the reason for adding JsonSource, etc. and how
> Romain imagined this should be done. I cannot think of a way where we would
> not need a JSON impl/dependency in our api for that case. Thus I don't like
> it. For me the PropertySource interface is perfectly enough.
> >>
> >>
> >>> My understanding was, that
> >>
> >>> we can have these classes in an extension module.
> >>
> >>
> >>Agree, that's why I don't like them in API and also not in core. core is
> kind of the RI impl vs extension should not be RI bound but imo should be
> portable and purely rely on the API. Happy to discuss this point though.
> Thus all this code you added should not be in the core module.
> >>
> >>> Adding the priority to the
> >>
> >>> file is only one way of defining it.
> >>Exactly. We might not even define this in the spec wording. All what
> counts is the final value returned by PropertySource#ordinal(). (And this
> value should not change during runtime).
> >>
> >>> There might be even use cases where
> >>
> >>> developers are not allowed to add overriding configs on their own
> deployed
> >>> with the application code.
> >>But in that case you need a SecurityManager. All other ways are not save.
> >>
> >>
> >>> URL is not a real abstraction for a resoruce
> >>We don't handle resources. All we handle are PropertySources. I totally
> don't care about Resources at all. It's really only PropertySources. If you
> read the configuration from the database then you also don't have any
> Resources. It's just useless imo. Where the PropertySources get the info
> from is purely an internal implementation detail.
> >>
> >>LieGrue,
> >>strub
> >>
> >>
> >>
> >>
> >>> On Sunday, 4 January 2015, 11:19, Anatole Tresch <at...@gmail.com>
> wrote:
> >>> > Hi Mark
> >>>
> >>> why we should have these deps in the API module. My understanding was,
> that
> >>> we can have these classes in an extension module. You needs take it. I
> only
> >>> added the properties format by default because it is so common and the
> >>> parsing code is already there, so there is a chance someone builts its
> >>> config system only based on property files, just because he wants it
> to be
> >>> minimalistic. In that case he only needs the core module and go for it!
> >>>
> >>> But I still struggle with the model here: depending where the files are
> >>> located an other priority must be the result. Adding the priority to
> the
> >>> file is only one way of defining it. There might be even use cases
> where
> >>> developers are not allowed to add overriding configs on their own
> deployed
> >>> with the application code. And as I said, URL is not a real
> abstraction for
> >>> a resoruce...
> >>> So these things lack of several aspects I think must be covered...
> >>>
> >>> Anatole
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>> 2015-01-04 11:06 GMT+01:00 Mark Struberg <st...@yahoo.de>:
> >>>
> >>>>  >I would be more brutal: JsonSource(URL), PropertiesSource(URL),
> >>>>  YamlSource(URL) etc...
> >>>>
> >>>>
> >>>>  But then we would have JSON, YAML etc parsing code (and thus
> dependencies)
> >>>>  in our api module. Do you see any way we could avoid this?
> >>>>
> >>>>  LieGrue,
> >>>>  strub
> >>>>
> >>>>
> >>>>
> >>>>  On Sunday, 4 January 2015, 10:39, Romain Manni-Bucau <
> >>>>  rmannibucau@gmail.com> wrote:
> >>>>  >I would be more brutal: JsonSource(URL), PropertiesSource(URL),
> >>>>  YamlSource(URL) etc...
> >>>>  >URL is the unique Resource abstraction we need IMO for resources.
> >>> Updates
> >>>>  will be detected by a source related event (for files WatchService,
> for
> >>>>  other polling for instance or even manual trigger etc....). So no
> need of
> >>>>  lastModified etc in the API.
> >>>>  >Le 4 janv. 2015 10:33, "Mark Struberg"
> >>> <st...@yahoo.de> a écrit :
> >>>>  >
> >>>>  >>Spring logic is more advanced - and broken IMO.
> >>>>  >>Totally agree. This was always targeted to allow configuration from
> >>>>  inside the Spring XML files. This is essentially scripting. But we
> >>> don't
> >>>>  have this.
> >>>>  >>>This means all classloader usages would be excluded.
> >>>>  >>
> >>>>  >>No, it's perfectly fine to have _some_ PropertySources who read
> >>> up
> >>>>  values from the ClassPath. Those are default configs for the app.
> And this
> >>>>  also allows some kind of flexible application approach like just
> adding a
> >>>>  jar and overriding some of it's configuration values in your own
> >>> project.
> >>>>  >>
> >>>>  >>Of course there are also PropertySources (JNDI, env and system by
> >>>>  default but you could also add your own very easily) who don't rely
> on
> >>> the
> >>>>  ClassPath but 'inject' information from outside the application
> >>> (ops,
> >>>>  database, etc - whatever you like). And those PropertySources have a
> higher
> >>>>  ordinal than the property files from your classpath.
> >>>>  >>
> >>>>  >>
> >>>>  >>> If this is accepted you only need to be able to provide an URL
> >>>>  >>> to an existing source to be able to read it so format is the
> >>> source
> >>>>  >>> if it has an URL constructor which makes thing really easier
> >>> IMO.
> >>>>  >>
> >>>>  >>
> >>>>  >>That could be fine. If I understood you correctly then you would
> >>> add a
> >>>>  'BasePropertySource' (better name needed ofc). which is in the spi
> >>> package
> >>>>  of our api module? And it has a constructor with the URL it should
> read? Or
> >>>>  did I get this wrong?
> >>>>  >>
> >>>>
> >>>
> >>>
> >>>
> >>> --
> >>> *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*
> >>>
> >>
> >
> >
>

Re: [2/4] incubator-tamaya git commit: TAMAYA-42, 43, 44: Readded non Spring related parts. Simplified resource API. Readded other tests.

Posted by Mark Struberg <st...@yahoo.de>.
Ok I get it now. Some BasePropertySource which might be reused in 'userland' code for easily adding yet another ConfigSource which is behaviourially very close to what the will end up in core (for some default locations).
We still need to discuss how those 'default' PropertySources should behave though.

LieGrue,
strub




On Sunday, 4 January 2015, 12:39, Romain Manni-Bucau <rm...@gmail.com> wrote:
>
>In extensions for sure but url constructor as a common practise
>Le 4 janv. 2015 11:42, "Mark Struberg" <st...@yahoo.de> a écrit :
>
>> why we should have these deps in the API module.
>>
>>
>>I just wanted to hear the reason for adding JsonSource, etc. and how Romain imagined this should be done. I cannot think of a way where we would not need a JSON impl/dependency in our api for that case. Thus I don't like it. For me the PropertySource interface is perfectly enough.
>>
>>
>>> My understanding was, that
>>
>>> we can have these classes in an extension module.
>>
>>
>>Agree, that's why I don't like them in API and also not in core. core is kind of the RI impl vs extension should not be RI bound but imo should be portable and purely rely on the API. Happy to discuss this point though. Thus all this code you added should not be in the core module.
>>
>>> Adding the priority to the
>>
>>> file is only one way of defining it.
>>Exactly. We might not even define this in the spec wording. All what counts is the final value returned by PropertySource#ordinal(). (And this value should not change during runtime).
>>
>>> There might be even use cases where
>>
>>> developers are not allowed to add overriding configs on their own deployed
>>> with the application code.
>>But in that case you need a SecurityManager. All other ways are not save.
>>
>>
>>> URL is not a real abstraction for a resoruce
>>We don't handle resources. All we handle are PropertySources. I totally don't care about Resources at all. It's really only PropertySources. If you read the configuration from the database then you also don't have any Resources. It's just useless imo. Where the PropertySources get the info from is purely an internal implementation detail.
>>
>>LieGrue,
>>strub
>>
>>
>>
>>
>>> On Sunday, 4 January 2015, 11:19, Anatole Tresch <at...@gmail.com> wrote:
>>> > Hi Mark
>>>
>>> why we should have these deps in the API module. My understanding was, that
>>> we can have these classes in an extension module. You needs take it. I only
>>> added the properties format by default because it is so common and the
>>> parsing code is already there, so there is a chance someone builts its
>>> config system only based on property files, just because he wants it to be
>>> minimalistic. In that case he only needs the core module and go for it!
>>>
>>> But I still struggle with the model here: depending where the files are
>>> located an other priority must be the result. Adding the priority to the
>>> file is only one way of defining it. There might be even use cases where
>>> developers are not allowed to add overriding configs on their own deployed
>>> with the application code. And as I said, URL is not a real abstraction for
>>> a resoruce...
>>> So these things lack of several aspects I think must be covered...
>>>
>>> Anatole
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> 2015-01-04 11:06 GMT+01:00 Mark Struberg <st...@yahoo.de>:
>>>
>>>>  >I would be more brutal: JsonSource(URL), PropertiesSource(URL),
>>>>  YamlSource(URL) etc...
>>>>
>>>>
>>>>  But then we would have JSON, YAML etc parsing code (and thus dependencies)
>>>>  in our api module. Do you see any way we could avoid this?
>>>>
>>>>  LieGrue,
>>>>  strub
>>>>
>>>>
>>>>
>>>>  On Sunday, 4 January 2015, 10:39, Romain Manni-Bucau <
>>>>  rmannibucau@gmail.com> wrote:
>>>>  >I would be more brutal: JsonSource(URL), PropertiesSource(URL),
>>>>  YamlSource(URL) etc...
>>>>  >URL is the unique Resource abstraction we need IMO for resources.
>>> Updates
>>>>  will be detected by a source related event (for files WatchService, for
>>>>  other polling for instance or even manual trigger etc....). So no need of
>>>>  lastModified etc in the API.
>>>>  >Le 4 janv. 2015 10:33, "Mark Struberg"
>>> <st...@yahoo.de> a écrit :
>>>>  >
>>>>  >>Spring logic is more advanced - and broken IMO.
>>>>  >>Totally agree. This was always targeted to allow configuration from
>>>>  inside the Spring XML files. This is essentially scripting. But we
>>> don't
>>>>  have this.
>>>>  >>>This means all classloader usages would be excluded.
>>>>  >>
>>>>  >>No, it's perfectly fine to have _some_ PropertySources who read
>>> up
>>>>  values from the ClassPath. Those are default configs for the app. And this
>>>>  also allows some kind of flexible application approach like just adding a
>>>>  jar and overriding some of it's configuration values in your own
>>> project.
>>>>  >>
>>>>  >>Of course there are also PropertySources (JNDI, env and system by
>>>>  default but you could also add your own very easily) who don't rely on
>>> the
>>>>  ClassPath but 'inject' information from outside the application
>>> (ops,
>>>>  database, etc - whatever you like). And those PropertySources have a higher
>>>>  ordinal than the property files from your classpath.
>>>>  >>
>>>>  >>
>>>>  >>> If this is accepted you only need to be able to provide an URL
>>>>  >>> to an existing source to be able to read it so format is the
>>> source
>>>>  >>> if it has an URL constructor which makes thing really easier
>>> IMO.
>>>>  >>
>>>>  >>
>>>>  >>That could be fine. If I understood you correctly then you would
>>> add a
>>>>  'BasePropertySource' (better name needed ofc). which is in the spi
>>> package
>>>>  of our api module? And it has a constructor with the URL it should read? Or
>>>>  did I get this wrong?
>>>>  >>
>>>>
>>>
>>>
>>>
>>> --
>>> *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*
>>>
>>
>
>

Re: [2/4] incubator-tamaya git commit: TAMAYA-42, 43, 44: Readded non Spring related parts. Simplified resource API. Readded other tests.

Posted by Romain Manni-Bucau <rm...@gmail.com>.
In extensions for sure but url constructor as a common practise
Le 4 janv. 2015 11:42, "Mark Struberg" <st...@yahoo.de> a écrit :

> > why we should have these deps in the API module.
>
>
> I just wanted to hear the reason for adding JsonSource, etc. and how
> Romain imagined this should be done. I cannot think of a way where we would
> not need a JSON impl/dependency in our api for that case. Thus I don't like
> it. For me the PropertySource interface is perfectly enough.
>
>
> > My understanding was, that
>
> > we can have these classes in an extension module.
>
>
> Agree, that's why I don't like them in API and also not in core. core is
> kind of the RI impl vs extension should not be RI bound but imo should be
> portable and purely rely on the API. Happy to discuss this point though.
> Thus all this code you added should not be in the core module.
>
> > Adding the priority to the
>
> > file is only one way of defining it.
> Exactly. We might not even define this in the spec wording. All what
> counts is the final value returned by PropertySource#ordinal(). (And this
> value should not change during runtime).
>
> > There might be even use cases where
>
> > developers are not allowed to add overriding configs on their own
> deployed
> > with the application code.
> But in that case you need a SecurityManager. All other ways are not save.
>
>
> > URL is not a real abstraction for a resoruce
> We don't handle resources. All we handle are PropertySources. I totally
> don't care about Resources at all. It's really only PropertySources. If you
> read the configuration from the database then you also don't have any
> Resources. It's just useless imo. Where the PropertySources get the info
> from is purely an internal implementation detail.
>
> LieGrue,
> strub
>
>
>
>
> > On Sunday, 4 January 2015, 11:19, Anatole Tresch <at...@gmail.com>
> wrote:
> > > Hi Mark
> >
> > why we should have these deps in the API module. My understanding was,
> that
> > we can have these classes in an extension module. You needs take it. I
> only
> > added the properties format by default because it is so common and the
> > parsing code is already there, so there is a chance someone builts its
> > config system only based on property files, just because he wants it to
> be
> > minimalistic. In that case he only needs the core module and go for it!
> >
> > But I still struggle with the model here: depending where the files are
> > located an other priority must be the result. Adding the priority to the
> > file is only one way of defining it. There might be even use cases where
> > developers are not allowed to add overriding configs on their own
> deployed
> > with the application code. And as I said, URL is not a real abstraction
> for
> > a resoruce...
> > So these things lack of several aspects I think must be covered...
> >
> > Anatole
> >
> >
> >
> >
> >
> >
> >
> > 2015-01-04 11:06 GMT+01:00 Mark Struberg <st...@yahoo.de>:
> >
> >>  >I would be more brutal: JsonSource(URL), PropertiesSource(URL),
> >>  YamlSource(URL) etc...
> >>
> >>
> >>  But then we would have JSON, YAML etc parsing code (and thus
> dependencies)
> >>  in our api module. Do you see any way we could avoid this?
> >>
> >>  LieGrue,
> >>  strub
> >>
> >>
> >>
> >>  On Sunday, 4 January 2015, 10:39, Romain Manni-Bucau <
> >>  rmannibucau@gmail.com> wrote:
> >>  >I would be more brutal: JsonSource(URL), PropertiesSource(URL),
> >>  YamlSource(URL) etc...
> >>  >URL is the unique Resource abstraction we need IMO for resources.
> > Updates
> >>  will be detected by a source related event (for files WatchService, for
> >>  other polling for instance or even manual trigger etc....). So no need
> of
> >>  lastModified etc in the API.
> >>  >Le 4 janv. 2015 10:33, "Mark Struberg"
> > <st...@yahoo.de> a écrit :
> >>  >
> >>  >>Spring logic is more advanced - and broken IMO.
> >>  >>Totally agree. This was always targeted to allow configuration from
> >>  inside the Spring XML files. This is essentially scripting. But we
> > don't
> >>  have this.
> >>  >>>This means all classloader usages would be excluded.
> >>  >>
> >>  >>No, it's perfectly fine to have _some_ PropertySources who read
> > up
> >>  values from the ClassPath. Those are default configs for the app. And
> this
> >>  also allows some kind of flexible application approach like just
> adding a
> >>  jar and overriding some of it's configuration values in your own
> > project.
> >>  >>
> >>  >>Of course there are also PropertySources (JNDI, env and system by
> >>  default but you could also add your own very easily) who don't rely on
> > the
> >>  ClassPath but 'inject' information from outside the application
> > (ops,
> >>  database, etc - whatever you like). And those PropertySources have a
> higher
> >>  ordinal than the property files from your classpath.
> >>  >>
> >>  >>
> >>  >>> If this is accepted you only need to be able to provide an URL
> >>  >>> to an existing source to be able to read it so format is the
> > source
> >>  >>> if it has an URL constructor which makes thing really easier
> > IMO.
> >>  >>
> >>  >>
> >>  >>That could be fine. If I understood you correctly then you would
> > add a
> >>  'BasePropertySource' (better name needed ofc). which is in the spi
> > package
> >>  of our api module? And it has a constructor with the URL it should
> read? Or
> >>  did I get this wrong?
> >>  >>
> >>
> >
> >
> >
> > --
> > *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*
> >
>

Re: [2/4] incubator-tamaya git commit: TAMAYA-42, 43, 44: Readded non Spring related parts. Simplified resource API. Readded other tests.

Posted by Mark Struberg <st...@yahoo.de>.
> why we should have these deps in the API module.


I just wanted to hear the reason for adding JsonSource, etc. and how Romain imagined this should be done. I cannot think of a way where we would not need a JSON impl/dependency in our api for that case. Thus I don't like it. For me the PropertySource interface is perfectly enough.


> My understanding was, that

> we can have these classes in an extension module. 


Agree, that's why I don't like them in API and also not in core. core is kind of the RI impl vs extension should not be RI bound but imo should be portable and purely rely on the API. Happy to discuss this point though. Thus all this code you added should not be in the core module.

> Adding the priority to the

> file is only one way of defining it.
Exactly. We might not even define this in the spec wording. All what counts is the final value returned by PropertySource#ordinal(). (And this value should not change during runtime).

> There might be even use cases where

> developers are not allowed to add overriding configs on their own deployed
> with the application code.
But in that case you need a SecurityManager. All other ways are not save.


> URL is not a real abstraction for a resoruce
We don't handle resources. All we handle are PropertySources. I totally don't care about Resources at all. It's really only PropertySources. If you read the configuration from the database then you also don't have any Resources. It's just useless imo. Where the PropertySources get the info from is purely an internal implementation detail.

LieGrue,
strub




> On Sunday, 4 January 2015, 11:19, Anatole Tresch <at...@gmail.com> wrote:
> > Hi Mark
> 
> why we should have these deps in the API module. My understanding was, that
> we can have these classes in an extension module. You needs take it. I only
> added the properties format by default because it is so common and the
> parsing code is already there, so there is a chance someone builts its
> config system only based on property files, just because he wants it to be
> minimalistic. In that case he only needs the core module and go for it!
> 
> But I still struggle with the model here: depending where the files are
> located an other priority must be the result. Adding the priority to the
> file is only one way of defining it. There might be even use cases where
> developers are not allowed to add overriding configs on their own deployed
> with the application code. And as I said, URL is not a real abstraction for
> a resoruce...
> So these things lack of several aspects I think must be covered...
> 
> Anatole
> 
> 
> 
> 
> 
> 
> 
> 2015-01-04 11:06 GMT+01:00 Mark Struberg <st...@yahoo.de>:
> 
>>  >I would be more brutal: JsonSource(URL), PropertiesSource(URL),
>>  YamlSource(URL) etc...
>> 
>> 
>>  But then we would have JSON, YAML etc parsing code (and thus dependencies)
>>  in our api module. Do you see any way we could avoid this?
>> 
>>  LieGrue,
>>  strub
>> 
>> 
>> 
>>  On Sunday, 4 January 2015, 10:39, Romain Manni-Bucau <
>>  rmannibucau@gmail.com> wrote:
>>  >I would be more brutal: JsonSource(URL), PropertiesSource(URL),
>>  YamlSource(URL) etc...
>>  >URL is the unique Resource abstraction we need IMO for resources. 
> Updates
>>  will be detected by a source related event (for files WatchService, for
>>  other polling for instance or even manual trigger etc....). So no need of
>>  lastModified etc in the API.
>>  >Le 4 janv. 2015 10:33, "Mark Struberg" 
> <st...@yahoo.de> a écrit :
>>  >
>>  >>Spring logic is more advanced - and broken IMO.
>>  >>Totally agree. This was always targeted to allow configuration from
>>  inside the Spring XML files. This is essentially scripting. But we 
> don't
>>  have this.
>>  >>>This means all classloader usages would be excluded.
>>  >>
>>  >>No, it's perfectly fine to have _some_ PropertySources who read 
> up
>>  values from the ClassPath. Those are default configs for the app. And this
>>  also allows some kind of flexible application approach like just adding a
>>  jar and overriding some of it's configuration values in your own 
> project.
>>  >>
>>  >>Of course there are also PropertySources (JNDI, env and system by
>>  default but you could also add your own very easily) who don't rely on 
> the
>>  ClassPath but 'inject' information from outside the application 
> (ops,
>>  database, etc - whatever you like). And those PropertySources have a higher
>>  ordinal than the property files from your classpath.
>>  >>
>>  >>
>>  >>> If this is accepted you only need to be able to provide an URL
>>  >>> to an existing source to be able to read it so format is the 
> source
>>  >>> if it has an URL constructor which makes thing really easier 
> IMO.
>>  >>
>>  >>
>>  >>That could be fine. If I understood you correctly then you would 
> add a
>>  'BasePropertySource' (better name needed ofc). which is in the spi 
> package
>>  of our api module? And it has a constructor with the URL it should read? Or
>>  did I get this wrong?
>>  >>
>> 
> 
> 
> 
> -- 
> *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*
>

Re: [2/4] incubator-tamaya git commit: TAMAYA-42, 43, 44: Readded non Spring related parts. Simplified resource API. Readded other tests.

Posted by Anatole Tresch <at...@gmail.com>.
Hi Mark

why we should have these deps in the API module. My understanding was, that
we can have these classes in an extension module. You needs take it. I only
added the properties format by default because it is so common and the
parsing code is already there, so there is a chance someone builts its
config system only based on property files, just because he wants it to be
minimalistic. In that case he only needs the core module and go for it!

But I still struggle with the model here: depending where the files are
located an other priority must be the result. Adding the priority to the
file is only one way of defining it. There might be even use cases where
developers are not allowed to add overriding configs on their own deployed
with the application code. And as I said, URL is not a real abstraction for
a resoruce...
So these things lack of several aspects I think must be covered...

Anatole






2015-01-04 11:06 GMT+01:00 Mark Struberg <st...@yahoo.de>:

> >I would be more brutal: JsonSource(URL), PropertiesSource(URL),
> YamlSource(URL) etc...
>
>
> But then we would have JSON, YAML etc parsing code (and thus dependencies)
> in our api module. Do you see any way we could avoid this?
>
> LieGrue,
> strub
>
>
>
> On Sunday, 4 January 2015, 10:39, Romain Manni-Bucau <
> rmannibucau@gmail.com> wrote:
> >I would be more brutal: JsonSource(URL), PropertiesSource(URL),
> YamlSource(URL) etc...
> >URL is the unique Resource abstraction we need IMO for resources. Updates
> will be detected by a source related event (for files WatchService, for
> other polling for instance or even manual trigger etc....). So no need of
> lastModified etc in the API.
> >Le 4 janv. 2015 10:33, "Mark Struberg" <st...@yahoo.de> a écrit :
> >
> >>Spring logic is more advanced - and broken IMO.
> >>Totally agree. This was always targeted to allow configuration from
> inside the Spring XML files. This is essentially scripting. But we don't
> have this.
> >>>This means all classloader usages would be excluded.
> >>
> >>No, it's perfectly fine to have _some_ PropertySources who read up
> values from the ClassPath. Those are default configs for the app. And this
> also allows some kind of flexible application approach like just adding a
> jar and overriding some of it's configuration values in your own project.
> >>
> >>Of course there are also PropertySources (JNDI, env and system by
> default but you could also add your own very easily) who don't rely on the
> ClassPath but 'inject' information from outside the application (ops,
> database, etc - whatever you like). And those PropertySources have a higher
> ordinal than the property files from your classpath.
> >>
> >>
> >>> If this is accepted you only need to be able to provide an URL
> >>> to an existing source to be able to read it so format is the source
> >>> if it has an URL constructor which makes thing really easier IMO.
> >>
> >>
> >>That could be fine. If I understood you correctly then you would add a
> 'BasePropertySource' (better name needed ofc). which is in the spi package
> of our api module? And it has a constructor with the URL it should read? Or
> did I get this wrong?
> >>
>



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

Re: [2/4] incubator-tamaya git commit: TAMAYA-42, 43, 44: Readded non Spring related parts. Simplified resource API. Readded other tests.

Posted by Mark Struberg <st...@yahoo.de>.
>I would be more brutal: JsonSource(URL), PropertiesSource(URL), YamlSource(URL) etc...


But then we would have JSON, YAML etc parsing code (and thus dependencies) in our api module. Do you see any way we could avoid this?

LieGrue,
strub



On Sunday, 4 January 2015, 10:39, Romain Manni-Bucau <rm...@gmail.com> wrote:
>I would be more brutal: JsonSource(URL), PropertiesSource(URL), YamlSource(URL) etc...
>URL is the unique Resource abstraction we need IMO for resources. Updates will be detected by a source related event (for files WatchService, for other polling for instance or even manual trigger etc....). So no need of lastModified etc in the API.
>Le 4 janv. 2015 10:33, "Mark Struberg" <st...@yahoo.de> a écrit :
>
>>Spring logic is more advanced - and broken IMO.
>>Totally agree. This was always targeted to allow configuration from inside the Spring XML files. This is essentially scripting. But we don't have this.
>>>This means all classloader usages would be excluded.
>>
>>No, it's perfectly fine to have _some_ PropertySources who read up values from the ClassPath. Those are default configs for the app. And this also allows some kind of flexible application approach like just adding a jar and overriding some of it's configuration values in your own project.
>>
>>Of course there are also PropertySources (JNDI, env and system by default but you could also add your own very easily) who don't rely on the ClassPath but 'inject' information from outside the application (ops, database, etc - whatever you like). And those PropertySources have a higher ordinal than the property files from your classpath.
>>
>>
>>> If this is accepted you only need to be able to provide an URL
>>> to an existing source to be able to read it so format is the source
>>> if it has an URL constructor which makes thing really easier IMO.
>>
>>
>>That could be fine. If I understood you correctly then you would add a 'BasePropertySource' (better name needed ofc). which is in the spi package of our api module? And it has a constructor with the URL it should read? Or did I get this wrong?
>>

Re: [2/4] incubator-tamaya git commit: TAMAYA-42, 43, 44: Readded non Spring related parts. Simplified resource API. Readded other tests.

Posted by Anatole Tresch <at...@gmail.com>.
Hi

2015-01-04 10:39 GMT+01:00 Romain Manni-Bucau <rm...@gmail.com>:

> I would be more brutal: JsonSource(URL), PropertiesSource(URL),
> YamlSource(URL) etc...
>
​No, this is too constraint. You really want to register an URL handler for
every part of custom protocol? Globally in the system?
How about application specific protocols and resource mechanisms? How about
caching?​

​URL is a class: taking a class as an abstraction -- ooh, feels ugly for
me, I would expect an interface....​


> URL is the unique Resource abstraction we need IMO for resources. Updates
> will be detected by a source related event (for files WatchService, for
> other polling for instance or even manual trigger etc....). So no need of
> lastModified etc in the API.
>

​We can remove the lastModified and we can discuss to improve the Resource
interface ;-) ! But reducing everything to an URL fails IMO.​



> Le 4 janv. 2015 10:33, "Mark Struberg" <st...@yahoo.de> a écrit :
>
> > >Spring logic is more advanced - and broken IMO.
> > Totally agree. This was always targeted to allow configuration from
> inside
> > the Spring XML files. This is essentially scripting. But we don't have
> this.
> > >This means all classloader usages would be excluded.
> >
> > No, it's perfectly fine to have _some_ PropertySources who read up values
> > from the ClassPath. Those are default configs for the app. And this also
> > allows some kind of flexible application approach like just adding a jar
> > and overriding some of it's configuration values in your own project.
> >
> > Of course there are also PropertySources (JNDI, env and system by default
> > but you could also add your own very easily) who don't rely on the
> > ClassPath but 'inject' information from outside the application (ops,
> > database, etc - whatever you like). And those PropertySources have a
> higher
> > ordinal than the property files from your classpath.
> >
> >
> > > If this is accepted you only need to be able to provide an URL
> > > to an existing source to be able to read it so format is the source
> > > if it has an URL constructor which makes thing really easier IMO.
> >
> >
> > That could be fine. If I understood you correctly then you would add a
> > 'BasePropertySource' (better name needed ofc). which is in the spi
> package
> > of our api module? And it has a constructor with the URL it should read?
> Or
> > did I get this wrong?
> >
> > LieGrue,
> > strub
> >
> >
> > On Sunday, 4 January 2015, 10:15, Romain Manni-Bucau <
> > rmannibucau@gmail.com> wrote:
> > >
> > >Spring logic is more advanced - and broken IMO. It can read from a
> > particular jar depending syntax and where it is read from.
> > >It brings me to the first question we should have tackled: what is a
> > config? For me it is all values which can be hardcoded and then cant be
> > packaged inside the app - otherwise you break the predicate "i dont need
> to
> > update my app for a config update". This means all classloader usages
> would
> > be excluded. If this is accepted you only need to be able to provide an
> URL
> > to an existing source to be able to read it so format is the source if it
> > has an URL constructor which makes thing really easier IMO.
> > >Wdyt?
> > >
> > >Le 4 janv. 2015 10:09, "Mark Struberg" <st...@yahoo.de> a écrit :
> > >
> > >I just became aware that maybe my VOTE was not clear enough.
> > >>
> > >>> 2.) Wouldn't it be easier to write the functionality ourselves
> > >>> and be able to only implement the pieces we really need?
> > >>> Currently all we need is ClassLoader.getResources() and be done.
> > >>
> > >>My aim was not to implement ALL the functionality originally taken from
> > Spring but really only the things we need.
> > >>And essentially the following:
> > >>
> > >>> Currently all we need is ClassLoader.getResources() and be done.
> > >>
> > >>
> > >>Reading Properties from a resource is essentially a single line of
> code:
> > >>
> > >>
> >
> >>java.util.Properties.load(ClassLoader.getResource(fileUrl).openStream());
> > >>
> > >>I don't yet get the benefit of the other code. Please explain.
> > >>
> > >>
> > >>LieGrue,
> > >>strub
> > >>
> > >>
> > >>
> > >>
> > >>
> > >>> On Sunday, 4 January 2015, 9:10, Mark Struberg <st...@yahoo.de>
> > wrote:
> > >>> > Anatole, WHY do we need all of this?
> > >>>
> > >>> It is NOWHERE used!
> > >>>
> > >>> Why do we add 21 classes which don't provide anything useful to the
> > project?
> > >>> There was even a VOTE that we should keep it simple and just do the
> > things we
> > >>> need.
> > >>>
> > >>> I really don't get it. Is our goal to create a lightweight but
> flexible
> > >>> configuration system or is our goal to become big and fat?
> > >>>
> > >>>
> > >>> Maybe it makes sense but if so then please explain it to us.
> > >>>
> > >>>
> > >>> 1.) Why do we read in a specific format?
> > >>>
> > >>> All the system is handling String/String and only in the last step it
> > *probably*
> > >>> gets converted into a target Type. I fail to see the benefit. Please
> > explain it
> > >>> to us.
> > >>>
> > >>> 2.) Why do we need all the Resource implementations?
> > >>>
> > >>> Java provides Resource handling out of the box. Again: we don't need
> > any
> > >>> scripting. So why add some handling for dynamic scenarios which we do
> > not have?
> > >>> This is basically a copy of Spring.io. But we simply don't have
> > anything
> > >>> scripted in XML as Spring does. So why should we add it?
> > >>>
> > >>>
> > >>> I'm really tired of seeing code all over the place which is not
> > helpful for
> > >>> the project. Please don't add things we don't really need.
> > >>>
> > >>>
> > >>> LieGrue,
> > >>> strub
> > >>>
> > >>>
> > >>>
> > >>>
> > >>>
> > >>>
> > >>>
> > >>>>  On Sunday, 4 January 2015, 2:52, "anatole@apache.org"
> > >>> <an...@apache.org> wrote:
> > >>>>  >T AMAYA-42,43,44: Readded non Spring related parts. Simplified
> > resource
> > >>> API.
> > >>>>  Readded other tests.
> > >>>>
> > >>>>
> > >>>>  Project:
> > http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo
> > >>>>  Commit:
> > >>>
> > http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/cc237eb4
> > >>>>  Tree:
> > http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/cc237eb4
> > >>>>  Diff:
> > http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/cc237eb4
> > >>>>
> > >>>>  Branch: refs/heads/master
> > >>>>  Commit: cc237eb41b7d0c660261f451f47bbf07b7770c46
> > >>>>  Parents: 59a9e21
> > >>>>  Author: anatole <an...@apache.org>
> > >>>>  Authored: Sun Jan 4 02:17:56 2015 +0100
> > >>>>  Committer: anatole <an...@apache.org>
> > >>>>  Committed: Sun Jan 4 02:26:23 2015 +0100
> > >>>>
> > >>>>
> > ----------------------------------------------------------------------
> > >>>>  .../org/apache/tamaya/spi/PropertyFilter.java   |  10 +-
> > >>>>  .../core/PathBasedPropertySourceProvider.java   |  93 ++++++++++
> > >>>>  .../core/ResourcePropertySourceProvider.java    | 102 +++++++++++
> > >>>>  .../core/formats/ConfigurationFormat.java       |  53 ++++++
> > >>>>  .../tamaya/core/formats/PropertiesFormat.java   | 114 ++++++++++++
> > >>>>  .../core/formats/PropertiesXmlFormat.java       | 115 ++++++++++++
> > >>>>  .../core/internal/DefaultConfiguration.java     |  27 ++-
> > >>>>  .../internal/resource/ClassPathResource.java    | 178
> > +++++++++++++++++++
> > >>>>  .../resource/DefaultResourceLoader.java         |  93 ++++++++++
> > >>>>  .../core/internal/resource/FileResource.java    | 162
> > +++++++++++++++++
> > >>>>  .../internal/resource/InputStreamResource.java  | 117 ++++++++++++
> > >>>>  .../core/resources/InputStreamSupplier.java     |  37 ++++
> > >>>>  .../apache/tamaya/core/resources/Resource.java  | 115 ++++++++++++
> > >>>>  .../tamaya/core/resources/ResourceLoader.java   |  91 ++++++++++
> > >>>>  .../apache/tamaya/core/ConfigurationTest.java   |   6 +
> > >>>>  .../EnvironmentPropertySourceTest.java          |  70 --------
> > >>>>  .../TestPropertyDefaultSourceProvider.java      |  32 ++++
> > >>>>  .../core/testdata/TestPropertySource.java       |  55 ------
> > >>>>  .../testdata/TestPropertySourceProvider.java    |  32 ++++
> > >>>>  .../org.apache.tamaya.spi.PropertySource        |  19 --
> > >>>>  ...org.apache.tamaya.spi.PropertySourceProvider |  20 +++
> > >>>>  21 files changed, 1388 insertions(+), 153 deletions(-)
> > >>>>
> > ----------------------------------------------------------------------
> > >>>>
> > >>>>
> > >>>>
> > >>>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> > >>>>
> > ----------------------------------------------------------------------
> > >>>>  diff --git
> > a/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> > >>>>  b/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> > >>>>  index 7479008..c8626fc 100644
> > >>>>  --- a/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> > >>>>  +++ b/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> > >>>>  @@ -19,7 +19,7 @@
> > >>>>  package org.apache.tamaya.spi;
> > >>>>
> > >>>>
> > >>>>  -import java.util.Map;
> > >>>>  +import java.util.function.Function;
> > >>>>
> > >>>>  /**
> > >>>>    * <p>Interface for filtering the current map of properties during
> > >>> the
> > >>>>  evaluation of the chain of PropertySources.
> > >>>>  @@ -27,7 +27,7 @@ import java.util.Map;
> > >>>>    * hereby is defined by the corresponding {@code @Priority}
> > >>>>  annotation.</p>
> > >>>>    * <p>Filters </p>
> > >>>>    */
> > >>>>  -public interface PropertyFilter<T>{
> > >>>>  +public interface PropertyFilter{
> > >>>>
> > >>>>       /**
> > >>>>        * <p>Maps the current {@code valueToBeFiltered} value to a
> > >>> new
> > >>>>  value. The resulting value will be used as the result
> > >>>>  @@ -44,10 +44,10 @@ public interface PropertyFilter<T>{
> > >>>>        *
> > >>>>        * @param key the key accessed, not null.
> > >>>>        * @param valueToBeFiltered the value to be filtered, not
> null.
> > >>>>  -     * @param currentMap the current input property map, not null.
> > Can be
> > >>> used
> > >>>>  for resolution of the filtered value
> > >>>>  -     *                   or as datasource for additional
> > meta-information,
> > >>> such
> > >>>>  as categories, sensitivity etc.
> > >>>>  +     * @param propertyValueProvider accessor for reading
> additional
> > (eg
> > >>>>  metadata) properties to perform correct
> > >>>>  +     *                              filtering, never null.
> > >>>>        * @return the filtered map, never null.
> > >>>>        */
> > >>>>  -    String filterProperty(String key, String valueToBeFiltered,
> > >>>>  Map<String,String> currentMap);
> > >>>>  +    String filterProperty(String key, String valueToBeFiltered,
> > >>>>  Function<String,String> propertyValueProvider);
> > >>>>
> > >>>>  }
> > >>>>
> > >>>>
> > >>>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
> > >>>>
> > ----------------------------------------------------------------------
> > >>>>  diff --git
> > >>>>
> > >>>
> >
> a/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
> > >>>
> > >>>>
> > >>>
> >
> b/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
> > >>>>  new file mode 100644
> > >>>>  index 0000000..31dbf4b
> > >>>>  --- /dev/null
> > >>>>  +++
> > >>>>
> > >>>
> >
> b/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
> > >>>>  @@ -0,0 +1,93 @@
> > >>>>  +/*
> > >>>>  + * Licensed to the Apache Software Foundation (ASF) under one
> > >>>>  + * or more contributor license agreements.  See the NOTICE file
> > >>>>  + * distributed with this work for additional information
> > >>>>  + * regarding copyright ownership.  The ASF licenses this file
> > >>>>  + * to you under the Apache License, Version 2.0 (the
> > >>>>  + * "License"); you may not use this file except in compliance
> > >>>>  + * with the License.  You may obtain a copy of the License at
> > >>>>  + *
> > >>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
> > >>>>  + *
> > >>>>  + * Unless required by applicable law or agreed to in writing,
> > >>>>  + * software distributed under the License is distributed on an
> > >>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>>>  + * KIND, either express or implied.  See the License for the
> > >>>>  + * specific language governing permissions and limitations
> > >>>>  + * under the License.
> > >>>>  + */
> > >>>>  +package org.apache.tamaya.core;
> > >>>>  +
> > >>>>  +import org.apache.tamaya.core.formats.ConfigurationFormat;
> > >>>>  +import org.apache.tamaya.core.resources.Resource;
> > >>>>  +import org.apache.tamaya.core.resources.ResourceLoader;
> > >>>>  +import org.apache.tamaya.spi.PropertySource;
> > >>>>  +import org.apache.tamaya.spi.PropertySourceProvider;
> > >>>>  +import org.apache.tamaya.spi.ServiceContext;
> > >>>>  +
> > >>>>  +import java.util.ArrayList;
> > >>>>  +import java.util.Arrays;
> > >>>>  +import java.util.Collection;
> > >>>>  +import java.util.List;
> > >>>>  +import java.util.Objects;
> > >>>>  +import java.util.logging.Level;
> > >>>>  +import java.util.logging.Logger;
> > >>>>  +
> > >>>>  +/**
> > >>>>  + * Implementation of a {@link PropertySourceProvider} that reads
> > >>>>  configuration from some given resource paths
> > >>>>  + * and using the given formats. The resource path are resolved
> > using the
> > >>>>  current
> > >>>>  + * {@link org.apache.tamaya.core.resources.ResourceLoader} active.
> > >>>>  + */
> > >>>>  +public class PathBasedPropertySourceProvider implements
> > >>> PropertySourceProvider
> > >>>>  {
> > >>>>  +    /** The logger used. */
> > >>>>  +    private static final Logger LOG =
> > >>>>  Logger.getLogger(PathBasedPropertySourceProvider.class.getName());
> > >>>>  +    /** The property source base name, will be used for creating a
> > useful
> > >>> name
> > >>>>  of the
> > >>>>  +     * {@link org.apache.tamaya.spi.PropertySource} created. */
> > >>>>  +    private String sourceName;
> > >>>>  +    /** The config formats supported for the given
> location/resource
> > >>> paths. */
> > >>>>  +    private List<ConfigurationFormat> configFormats = new
> > >>>>  ArrayList<>();
> > >>>>  +    /** The paths to be evaluated. */
> > >>>>  +    private List<String> paths = new ArrayList<>();
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Creates a new instance.
> > >>>>  +     * @param sourceName the base name of the configuration, used
> > for
> > >>> creating
> > >>>>  PropertySource child names.
> > >>>>  +     * @param formats the formats to be used, not null, not empty.
> > >>>>  +     * @param paths the paths to be resolved, not null, not empty.
> > >>>>  +     */
> > >>>>  +    public PathBasedPropertySourceProvider(String sourceName,
> > >>>>  List<ConfigurationFormat> formats, String... paths) {
> > >>>>  +        this.sourceName = Objects.requireNonNull(sourceName);
> > >>>>  +
> this.configFormats.addAll(Objects.requireNonNull(formats));
> > >>>>  +
> > this.paths.addAll(Arrays.asList(Objects.requireNonNull(paths)));
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Creates a new instance.
> > >>>>  +     * @param sourceName the base name of the configuration, used
> > for
> > >>> creating
> > >>>>  PropertySource child names.
> > >>>>  +     * @param format the format to be used.
> > >>>>  +     * @param paths the paths to be resolved, not null, not empty.
> > >>>>  +     */
> > >>>>  +    public PathBasedPropertySourceProvider(String sourceName,
> > >>>>  ConfigurationFormat format, String... paths) {
> > >>>>  +        this.sourceName = Objects.requireNonNull(sourceName);
> > >>>>  +        this.configFormats.add(Objects.requireNonNull(format));
> > >>>>  +
> > this.paths.addAll(Arrays.asList(Objects.requireNonNull(paths)));
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    @Override
> > >>>>  +    public Collection<PropertySource> getPropertySources() {
> > >>>>  +        List<PropertySource> propertySources = new
> > >>> ArrayList<>();
> > >>>>  +        paths.forEach((path) -> {
> > >>>>  +            for (Resource res :
> > >>>>
> > >>>
> >
> ServiceContext.getInstance().getService(ResourceLoader.class).get().getResources(path))
> > >>>
> > >>>>  {
> > >>>>  +                try {
> > >>>>  +                    for (ConfigurationFormat format :
> configFormats)
> > >>> {
> > >>>>  +
> > >>>>  propertySources.addAll(format.readConfiguration(sourceName, res));
> > >>>>  +                    }
> > >>>>  +                } catch (Exception e) {
> > >>>>  +                    LOG.log(Level.WARNING, "Failed to add resource
> > >>> based
> > >>>>  config: " + res.getName(), e);
> > >>>>  +                }
> > >>>>  +            }
> > >>>>  +        });
> > >>>>  +        return propertySources;
> > >>>>  +    }
> > >>>>  +
> > >>>>  +}
> > >>>>
> > >>>>
> > >>>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
> > >>>>
> > ----------------------------------------------------------------------
> > >>>>  diff --git
> > >>>>
> > >>>
> >
> a/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
> > >>>>
> > >>>
> >
> b/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
> > >>>>  new file mode 100644
> > >>>>  index 0000000..de6b578
> > >>>>  --- /dev/null
> > >>>>  +++
> > >>>>
> > >>>
> >
> b/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
> > >>>>  @@ -0,0 +1,102 @@
> > >>>>  +/*
> > >>>>  + * Licensed to the Apache Software Foundation (ASF) under one
> > >>>>  + * or more contributor license agreements.  See the NOTICE file
> > >>>>  + * distributed with this work for additional information
> > >>>>  + * regarding copyright ownership.  The ASF licenses this file
> > >>>>  + * to you under the Apache License, Version 2.0 (the
> > >>>>  + * "License"); you may not use this file except in compliance
> > >>>>  + * with the License.  You may obtain a copy of the License at
> > >>>>  + *
> > >>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
> > >>>>  + *
> > >>>>  + * Unless required by applicable law or agreed to in writing,
> > >>>>  + * software distributed under the License is distributed on an
> > >>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>>>  + * KIND, either express or implied.  See the License for the
> > >>>>  + * specific language governing permissions and limitations
> > >>>>  + * under the License.
> > >>>>  + */
> > >>>>  +package org.apache.tamaya.core;
> > >>>>  +
> > >>>>  +import org.apache.tamaya.core.formats.ConfigurationFormat;
> > >>>>  +import org.apache.tamaya.core.resources.Resource;
> > >>>>  +import org.apache.tamaya.spi.PropertySource;
> > >>>>  +import org.apache.tamaya.spi.PropertySourceProvider;
> > >>>>  +
> > >>>>  +import java.util.ArrayList;
> > >>>>  +import java.util.Arrays;
> > >>>>  +import java.util.Collection;
> > >>>>  +import java.util.List;
> > >>>>  +import java.util.Objects;
> > >>>>  +import java.util.logging.Logger;
> > >>>>  +
> > >>>>  +/**
> > >>>>  + * Implementation of a {@link
> > >>>>  org.apache.tamaya.spi.PropertySourceProvider} that is based on a
> > single
> > >>> resource
> > >>>>  + * and a number of formats.
> > >>>>  + */
> > >>>>  +public class ResourcePropertySourceProvider implements
> > >>> PropertySourceProvider
> > >>>>  {
> > >>>>  +    /** The logger used. */
> > >>>>  +    private static final Logger LOG =
> > >>>>  Logger.getLogger(ResourcePropertySourceProvider.class.getName());
> > >>>>  +    /** The supported formats. */
> > >>>>  +    private List<ConfigurationFormat> formats = new
> > >>> ArrayList<>();
> > >>>>  +    /** The resource. */
> > >>>>  +    private Resource resource;
> > >>>>  +    /** The source name used for creating the PropertySource
> names.
> > */
> > >>>>  +    private String sourceName;
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Creates a new instance.
> > >>>>  +     * @param resource the {@link
> > >>>>  org.apache.tamaya.core.resources.Resource}, not null.
> > >>>>  +     * @param formats the supported formats, not empty.
> > >>>>  +     */
> > >>>>  +    public ResourcePropertySourceProvider(String sourceName,
> > Resource
> > >>> resource,
> > >>>>  ConfigurationFormat... formats) {
> > >>>>  +        this(sourceName, resource, Arrays.asList(formats));
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Creates a new instance.
> > >>>>  +     * @param resource the {@link
> > >>>>  org.apache.tamaya.core.resources.Resource}, not null.
> > >>>>  +     * @param formats the supported formats, not empty.
> > >>>>  +     */
> > >>>>  +    public ResourcePropertySourceProvider(String sourceName,
> > Resource
> > >>> resource,
> > >>>>  List<ConfigurationFormat> formats) {
> > >>>>  +        this.resource = Objects.requireNonNull(resource);
> > >>>>  +        this.sourceName = Objects.requireNonNull(sourceName);
> > >>>>  +        if(formats.size()==0){
> > >>>>  +            throw new IllegalArgumentException("Format
> > >>> required.");
> > >>>>  +        }
> > >>>>  +        this.formats.addAll(formats);
> > >>>>  +    }
> > >>>>  +
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Get the underlying resource.
> > >>>>  +     *
> > >>>>  +     * @return the underlying resource, never null.
> > >>>>  +     */
> > >>>>  +    public Resource getResource() {
> > >>>>  +        return this.resource;
> > >>>>  +    }
> > >>>>  +
> > >>>>  +
> > >>>>  +    @Override
> > >>>>  +    public String toString() {
> > >>>>  +        return "ResourcePropertySourceProvider{" +
> > >>>>  +                "resource=" + resource +
> > >>>>  +                ", formats=+" + formats +
> > >>>>  +                '}';
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    @Override
> > >>>>  +    public Collection<PropertySource> getPropertySources() {
> > >>>>  +        List<PropertySource> propertySources = new
> > >>> ArrayList<>();
> > >>>>  +        for (ConfigurationFormat format : formats) {
> > >>>>  +            try {
> > >>>>  +
> > >>> propertySources.addAll(format.readConfiguration(sourceName,
> > >>>>  resource));
> > >>>>  +            } catch (Exception e) {
> > >>>>  +                LOG.info(() -> "Format was not matching: " +
> > >>>>  format + " for resource: " + resource.getName());
> > >>>>  +            }
> > >>>>  +        }
> > >>>>  +        return propertySources;
> > >>>>  +    }
> > >>>>  +
> > >>>>  +}
> > >>>>
> > >>>>
> > >>>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
> > >>>>
> > ----------------------------------------------------------------------
> > >>>>  diff --git
> > >>>>
> > >>>
> >
> a/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
> > >>>>
> > >>>
> >
> b/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
> > >>>>  new file mode 100644
> > >>>>  index 0000000..5d289bb
> > >>>>  --- /dev/null
> > >>>>  +++
> > >>>
> >
> b/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
> > >>>>  @@ -0,0 +1,53 @@
> > >>>>  +/*
> > >>>>  + * Licensed to the Apache Software Foundation (ASF) under one
> > >>>>  + * or more contributor license agreements.  See the NOTICE file
> > >>>>  + * distributed with this work for additional information
> > >>>>  + * regarding copyright ownership.  The ASF licenses this file
> > >>>>  + * to you under the Apache License, Version 2.0 (the
> > >>>>  + * "License"); you may not use this file except in compliance
> > >>>>  + * with the License.  You may obtain a copy of the License at
> > >>>>  + *
> > >>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
> > >>>>  + *
> > >>>>  + * Unless required by applicable law or agreed to in writing,
> > >>>>  + * software distributed under the License is distributed on an
> > >>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>>>  + * KIND, either express or implied.  See the License for the
> > >>>>  + * specific language governing permissions and limitations
> > >>>>  + * under the License.
> > >>>>  + */
> > >>>>  +package org.apache.tamaya.core.formats;
> > >>>>  +
> > >>>>  +import org.apache.tamaya.core.resources.Resource;
> > >>>>  +import org.apache.tamaya.spi.PropertySource;
> > >>>>  +
> > >>>>  +import java.io.IOException;
> > >>>>  +import java.util.Collection;
> > >>>>  +
> > >>>>  +/**
> > >>>>  + * Implementations current this class encapsulate the mechanism
> how
> > to
> > >>> read a
> > >>>>  + * resource including interpreting the format correctly (e.g. xml
> > vs.
> > >>>>  + * properties). In most cases file only contains entries of the
> same
> > >>> priority,
> > >>>>  which would then
> > >>>>  + * result in only one {@link PropertySource}. Complex file
> formats,
> > >>>>  hoiwever, may contain entries
> > >>>>  + * of different priorities. In this cases, each ordinal type found
> > must be
> > >>>
> > >>>>  returned as a separate
> > >>>>  + * {@link PropertySource} instance.
> > >>>>  + */
> > >>>>  +@FunctionalInterface
> > >>>>  +public interface ConfigurationFormat {
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Reads a list {@link org.apache.tamaya.spi.PropertySource}
> > >>> instances
> > >>>>  from a resource, using this format.
> > >>>>  +     * If the configuration format only contains entries of one
> > ordinal
> > >>> type,
> > >>>>  normally only one single
> > >>>>  +     * instance of PropertySource is returned. Nevertheless custom
> > formats
> > >>> may
> > >>>>  contain different sections or parts,
> > >>>>  +     * where each part maps to a different target rdinal (eg
> > defaults,
> > >>> domain
> > >>>>  config and app config). In the
> > >>>>  +     * ladder case multiple PropertySources can be returned, each
> > one with
> > >>> its
> > >>>>  own ordinal and the corresponding
> > >>>>  +     * entries.
> > >>>>  +     *
> > >>>>  +     * @param sourceName name to be used for constructing a useful
> > name
> > >>> for the
> > >>>>  created
> > >>>>  +     *                   {@link
> > org.apache.tamaya.spi.PropertySource}
> > >>>
> > >>>>  instances.
> > >>>>  +     * @param resource   the configuration resource, not null
> > >>>>  +     * @return the corresponding {@link
> > >>>>  org.apache.tamaya.spi.PropertySource} instances, never {@code
> null}.
> > >>>>  +     */
> > >>>>  +    Collection<PropertySource> readConfiguration(String
> sourceName,
> > >>>>  Resource resource) throws IOException;
> > >>>>  +
> > >>>>  +}
> > >>>>
> > >>>>
> > >>>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
> > >>>>
> > ----------------------------------------------------------------------
> > >>>>  diff --git
> > >>>>
> > a/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
> > >>>>
> > b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
> > >>>>  new file mode 100644
> > >>>>  index 0000000..3584f8e
> > >>>>  --- /dev/null
> > >>>>  +++
> > >>>
> > b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
> > >>>>  @@ -0,0 +1,114 @@
> > >>>>  +/*
> > >>>>  + * Licensed to the Apache Software Foundation (ASF) under one
> > >>>>  + * or more contributor license agreements.  See the NOTICE file
> > >>>>  + * distributed with this work for additional information
> > >>>>  + * regarding copyright ownership.  The ASF licenses this file
> > >>>>  + * to you under the Apache License, Version 2.0 (the
> > >>>>  + * "License"); you may not use this file except in compliance
> > >>>>  + * with the License.  You may obtain a copy of the License at
> > >>>>  + *
> > >>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
> > >>>>  + *
> > >>>>  + * Unless required by applicable law or agreed to in writing,
> > >>>>  + * software distributed under the License is distributed on an
> > >>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>>>  + * KIND, either express or implied.  See the License for the
> > >>>>  + * specific language governing permissions and limitations
> > >>>>  + * under the License.
> > >>>>  + */
> > >>>>  +package org.apache.tamaya.core.formats;
> > >>>>  +
> > >>>>  +import org.apache.tamaya.core.resources.Resource;
> > >>>>  +import org.apache.tamaya.spi.PropertySource;
> > >>>>  +
> > >>>>  +import java.io.InputStream;
> > >>>>  +import java.util.ArrayList;
> > >>>>  +import java.util.Collection;
> > >>>>  +import java.util.Collections;
> > >>>>  +import java.util.List;
> > >>>>  +import java.util.Map;
> > >>>>  +import java.util.Optional;
> > >>>>  +import java.util.Properties;
> > >>>>  +import java.util.logging.Level;
> > >>>>  +import java.util.logging.Logger;
> > >>>>  +
> > >>>>  +/**
> > >>>>  + * Implementation of a {@link
> > >>>>  org.apache.tamaya.core.formats.ConfigurationFormat} for -properties
> > files.
> > >>>>  + *
> > >>>>  + * @see java.util.Properties#load(java.io.InputStream)
> > >>>>  + */
> > >>>>  +public class PropertiesFormat implements ConfigurationFormat {
> > >>>>  +    /**
> > >>>>  +     * The logger.
> > >>>>  +     */
> > >>>>  +    private final static Logger LOG =
> > >>>>  Logger.getLogger(PropertiesFormat.class.getName());
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * The target ordinal.
> > >>>>  +     */
> > >>>>  +    private int ordinal;
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Creates a new format instance, hereby producing entries
> with
> > the
> > >>> given
> > >>>>  ordinal, if not overridden by the
> > >>>>  +     * configuration itself.
> > >>>>  +     * TODO document and implement override feature
> > >>>>  +     * @param ordinal the target ordinal.
> > >>>>  +     */
> > >>>>  +    public PropertiesFormat(int ordinal) {
> > >>>>  +        this.ordinal = ordinal;
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Get the target ordinal, produced by this format.
> > >>>>  +     *
> > >>>>  +     * @return the target ordinal
> > >>>>  +     */
> > >>>>  +    public int getOrdinal() {
> > >>>>  +        return ordinal;
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    @SuppressWarnings("unchecked")
> > >>>>  +    @Override
> > >>>>  +    public Collection<PropertySource> readConfiguration(String
> > >>> baseName,
> > >>>>  Resource resource) {
> > >>>>  +        final String sourceName =
> > >>>>  (baseName==null?"Properties:":baseName) + resource.getName();
> > >>>>  +        if (resource.exists()) {
> > >>>>  +            List<PropertySource> propertySources = new
> > >>>>  ArrayList<>();
> > >>>>  +            try (InputStream is = resource.getInputStream()) {
> > >>>>  +                final Properties p = new Properties();
> > >>>>  +                p.load(is);
> > >>>>  +                propertySources.add(new PropertySource() {
> > >>>>  +                    @Override
> > >>>>  +                    public int getOrdinal() {
> > >>>>  +                        return ordinal;
> > >>>>  +                    }
> > >>>>  +
> > >>>>  +                    @Override
> > >>>>  +                    public String getName() {
> > >>>>  +                        return sourceName;
> > >>>>  +                    }
> > >>>>  +
> > >>>>  +                    @Override
> > >>>>  +                    public Optional<String> get(String key) {
> > >>>>  +                        return
> > Optional.ofNullable(p.getProperty(key));
> > >>>>  +                    }
> > >>>>  +
> > >>>>  +                    @Override
> > >>>>  +                    public Map<String, String> getProperties()
> > >>> {
> > >>>>  +                        return Map.class.cast(p);
> > >>>>  +                    }
> > >>>>  +                });
> > >>>>  +                return propertySources;
> > >>>>  +            } catch (Exception e) {
> > >>>>  +                LOG.log(Level.FINEST, e, () -> "Failed to read
> > >>> config
> > >>>>  from resource: " + resource);
> > >>>>  +            }
> > >>>>  +        }
> > >>>>  +        return Collections.emptyList();
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    @Override
> > >>>>  +    public String toString() {
> > >>>>  +        return "PropertiesFormat{" +
> > >>>>  +                "ordinal=" + ordinal +
> > >>>>  +                '}';
> > >>>>  +    }
> > >>>>  +}
> > >>>>
> > >>>>
> > >>>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
> > >>>>
> > ----------------------------------------------------------------------
> > >>>>  diff --git
> > >>>>
> > >>>
> >
> a/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
> > >>>>
> > >>>
> >
> b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
> > >>>>  new file mode 100644
> > >>>>  index 0000000..3f77810
> > >>>>  --- /dev/null
> > >>>>  +++
> > >>>
> >
> b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
> > >>>>  @@ -0,0 +1,115 @@
> > >>>>  +/*
> > >>>>  + * Licensed to the Apache Software Foundation (ASF) under one
> > >>>>  + * or more contributor license agreements.  See the NOTICE file
> > >>>>  + * distributed with this work for additional information
> > >>>>  + * regarding copyright ownership.  The ASF licenses this file
> > >>>>  + * to you under the Apache License, Version 2.0 (the
> > >>>>  + * "License"); you may not use this file except in compliance
> > >>>>  + * with the License.  You may obtain a copy of the License at
> > >>>>  + *
> > >>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
> > >>>>  + *
> > >>>>  + * Unless required by applicable law or agreed to in writing,
> > >>>>  + * software distributed under the License is distributed on an
> > >>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>>>  + * KIND, either express or implied.  See the License for the
> > >>>>  + * specific language governing permissions and limitations
> > >>>>  + * under the License.
> > >>>>  + */
> > >>>>  +package org.apache.tamaya.core.formats;
> > >>>>  +
> > >>>>  +import org.apache.tamaya.core.resources.Resource;
> > >>>>  +import org.apache.tamaya.spi.PropertySource;
> > >>>>  +
> > >>>>  +import java.io.InputStream;
> > >>>>  +import java.util.ArrayList;
> > >>>>  +import java.util.Collection;
> > >>>>  +import java.util.Collections;
> > >>>>  +import java.util.List;
> > >>>>  +import java.util.Map;
> > >>>>  +import java.util.Optional;
> > >>>>  +import java.util.Properties;
> > >>>>  +import java.util.logging.Level;
> > >>>>  +import java.util.logging.Logger;
> > >>>>  +
> > >>>>  +/**
> > >>>>  + * Implementation of a {@link
> > >>>>  org.apache.tamaya.core.formats.ConfigurationFormat} for xml
> property
> > >>>>  + * files.
> > >>>>  + *
> > >>>>  + * @see java.util.Properties#loadFromXML(java.io.InputStream)
> > >>>>  + */
> > >>>>  +public class PropertiesXmlFormat implements ConfigurationFormat {
> > >>>>  +    /**
> > >>>>  +     * The logger.
> > >>>>  +     */
> > >>>>  +    private final static Logger LOG =
> > >>>>  Logger.getLogger(PropertiesXmlFormat.class.getName());
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * The target ordinal.
> > >>>>  +     */
> > >>>>  +    private int ordinal;
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Creates a new format instance, producing entries for the
> > given
> > >>> ordinal,
> > >>>>  if not overridden by a
> > >>>>  +     * config entry itself.
> > >>>>  +     * TODO document and implement override feature
> > >>>>  +     * @param ordinal the target ordinal.
> > >>>>  +     */
> > >>>>  +    public PropertiesXmlFormat(int ordinal) {
> > >>>>  +        this.ordinal = ordinal;
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Get the target ordinal, produced by this format.
> > >>>>  +     *
> > >>>>  +     * @return the target ordinal
> > >>>>  +     */
> > >>>>  +    public int getOrdinal() {
> > >>>>  +        return ordinal;
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    @SuppressWarnings("unchecked")
> > >>>>  +    @Override
> > >>>>  +    public Collection<PropertySource> readConfiguration(String
> > >>> baseName,
> > >>>>  Resource resource) {
> > >>>>  +        if (resource.exists()) {
> > >>>>  +            final String sourceName =
> > >>>>  (baseName==null?"Properties:":baseName) + resource.getName();
> > >>>>  +            List<PropertySource> propertySources = new
> > >>>>  ArrayList<>();
> > >>>>  +            try (InputStream is = resource.getInputStream()) {
> > >>>>  +                final Properties p = new Properties();
> > >>>>  +                p.loadFromXML(is);
> > >>>>  +                propertySources.add(new PropertySource() {
> > >>>>  +                    @Override
> > >>>>  +                    public int getOrdinal() {
> > >>>>  +                        return ordinal;
> > >>>>  +                    }
> > >>>>  +
> > >>>>  +                    @Override
> > >>>>  +                    public String getName() {
> > >>>>  +                        return sourceName;
> > >>>>  +                    }
> > >>>>  +
> > >>>>  +                    @Override
> > >>>>  +                    public Optional<String> get(String key) {
> > >>>>  +                        return
> > Optional.ofNullable(p.getProperty(key));
> > >>>>  +                    }
> > >>>>  +
> > >>>>  +                    @Override
> > >>>>  +                    public Map<String, String> getProperties()
> > >>> {
> > >>>>  +                        return Map.class.cast(p);
> > >>>>  +                    }
> > >>>>  +                });
> > >>>>  +                return propertySources;
> > >>>>  +            } catch (Exception e) {
> > >>>>  +                LOG.log(Level.FINEST, e, () -> "Failed to read
> > >>> config
> > >>>>  from resource: " + resource);
> > >>>>  +            }
> > >>>>  +        }
> > >>>>  +        return Collections.emptyList();
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    @Override
> > >>>>  +    public String toString() {
> > >>>>  +        return "PropertiesXmlFormat{" +
> > >>>>  +                "ordinal=" + ordinal +
> > >>>>  +                '}';
> > >>>>  +    }
> > >>>>  +}
> > >>>>
> > >>>>
> > >>>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> > >>>>
> > ----------------------------------------------------------------------
> > >>>>  diff --git
> > >>>>
> > >>>
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> > >>>>
> > >>>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> > >>>>  index 0a39b7d..3769e27 100644
> > >>>>  ---
> > >>>>
> > >>>
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> > >>>>  +++
> > >>>>
> > >>>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> > >>>>  @@ -22,6 +22,7 @@ import org.apache.tamaya.ConfigException;
> > >>>>  import org.apache.tamaya.Configuration;
> > >>>>  import org.apache.tamaya.spi.ConfigurationContext;
> > >>>>  import org.apache.tamaya.spi.PropertyConverter;
> > >>>>  +import org.apache.tamaya.spi.PropertyFilter;
> > >>>>  import org.apache.tamaya.spi.PropertySource;
> > >>>>  import org.apache.tamaya.spi.ServiceContext;
> > >>>>
> > >>>>  @@ -33,6 +34,7 @@ import java.util.Map;
> > >>>>  import java.util.Optional;
> > >>>>  import java.util.logging.Level;
> > >>>>  import java.util.logging.Logger;
> > >>>>  +import java.util.stream.Collectors;
> > >>>>
> > >>>>  /**
> > >>>>    * Implementation of the Configuration API. This class uses the
> > current
> > >>>>  {@link ConfigurationContext} to evaluate the
> > >>>>  @@ -56,13 +58,21 @@ public class DefaultConfiguration implements
> > >>> Configuration
> > >>>>  {
> > >>>>       @Override
> > >>>>       public Optional<String> get(String key) {
> > >>>>           List<PropertySource> propertySources =
> > >>>>
> > >>>
> >
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertySources();
> > >>>>  +        String unfilteredValue = null;
> > >>>>           for (PropertySource propertySource : propertySources) {
> > >>>>               Optional<String> value = propertySource.get(key);
> > >>>>               if (value.isPresent()) {
> > >>>>  -                return value;
> > >>>>  +                unfilteredValue = value.get();
> > >>>>  +                break;
> > >>>>               }
> > >>>>           }
> > >>>>  -        return Optional.empty();
> > >>>>  +        // Apply filters to values, prevent values filtered to
> null!
> > >>>>  +        for(PropertyFilter filter:
> > >>>>  +
> > >>>>
> > >>>
> >
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyFilters()){
> > >>>>  +            unfilteredValue = filter.filterProperty(key,
> > unfilteredValue,
> > >>>>  +                    (String k) ->
> > >>> key.equals(k)?null:get(k).orElse(null));
> > >>>>  +        }
> > >>>>  +        return Optional.ofNullable(unfilteredValue);
> > >>>>       }
> > >>>>
> > >>>>       @Override
> > >>>>  @@ -83,7 +93,15 @@ public class DefaultConfiguration implements
> > >>> Configuration
> > >>>>  {
> > >>>>                   LOG.log(Level.SEVERE, "Error adding properties
> from
> > >>>>  PropertySource: " + propertySource +", ignoring
> > >>> PropertySource.",
> > >>>>  e);
> > >>>>               }
> > >>>>           }
> > >>>>  -        return result;
> > >>>>  +        // Apply filters to values, prevent values filtered to
> null!
> > >>>>  +        for(PropertyFilter filter:
> > >>>>  +
> > >>>>
> > >>>
> >
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyFilters()){
> > >>>>  +            result.replaceAll((k,v) -> filter.filterProperty(k, v,
> > >>>>  +                    (String k2) ->
> > >>> k2.equals(k)?null:get(k2).orElse(null)));
> > >>>>  +        }
> > >>>>  +        // Remove null values
> > >>>>  +        return result.entrySet().parallelStream().filter((e) ->
> > >>>>  e.getValue()!=null).collect(
> > >>>>  +                Collectors.toMap((e) -> e.getKey(), (e) ->
> > >>>>  e.getValue()));
> > >>>>       }
> > >>>>
> > >>>>       /**
> > >>>>  @@ -101,7 +119,8 @@ public class DefaultConfiguration implements
> > >>> Configuration
> > >>>>  {
> > >>>>       public <T> Optional<T> get(String key, Class<T>
> > >>> type)
> > >>>>  {
> > >>>>           Optional<String> value = get(key);
> > >>>>           if (value.isPresent()) {
> > >>>>  -            List<PropertyConverter<T>> converters =
> > >>>>
> > >>>
> >
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyConverters(type);
> > >>>>  +            List<PropertyConverter<T>> converters =
> > >>>>  ServiceContext.getInstance().getService(ConfigurationContext.class)
> > >>>>  +                    .get().getPropertyConverters(type);
> > >>>>               for (PropertyConverter<T> converter : converters) {
> > >>>>                   try {
> > >>>>                       T t = converter.convert(value.get());
> > >>>>
> > >>>>
> > >>>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
> > >>>>
> > ----------------------------------------------------------------------
> > >>>>  diff --git
> > >>>>
> > >>>
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
> > >>>
> > >>>>
> > >>>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
> > >>>>  new file mode 100644
> > >>>>  index 0000000..21806cd
> > >>>>  --- /dev/null
> > >>>>  +++
> > >>>>
> > >>>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
> > >>>>  @@ -0,0 +1,178 @@
> > >>>>  +/*
> > >>>>  + * Licensed to the Apache Software Foundation (ASF) under one
> > >>>>  + * or more contributor license agreements.  See the NOTICE file
> > >>>>  + * distributed with this work for additional information
> > >>>>  + * regarding copyright ownership.  The ASF licenses this file
> > >>>>  + * to you under the Apache License, Version 2.0 (the
> > >>>>  + * "License"); you may not use this file except in compliance
> > >>>>  + * with the License.  You may obtain a copy of the License at
> > >>>>  + *
> > >>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
> > >>>>  + *
> > >>>>  + * Unless required by applicable law or agreed to in writing,
> > >>>>  + * software distributed under the License is distributed on an
> > >>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>>>  + * KIND, either express or implied.  See the License for the
> > >>>>  + * specific language governing permissions and limitations
> > >>>>  + * under the License.
> > >>>>  + */
> > >>>>  +package org.apache.tamaya.core.internal.resource;
> > >>>>  +
> > >>>>  +import org.apache.tamaya.core.resources.Resource;
> > >>>>  +
> > >>>>  +import java.io.IOException;
> > >>>>  +import java.io.InputStream;
> > >>>>  +import java.net.URI;
> > >>>>  +import java.net.URISyntaxException;
> > >>>>  +import java.net.URL;
> > >>>>  +import java.util.Objects;
> > >>>>  +
> > >>>>  +/**
> > >>>>  + * Implementation of {@link Resource} to be loaded from the
> > >>> classpath.
> > >>>>  + */
> > >>>>  +public class ClassPathResource implements Resource {
> > >>>>  +
> > >>>>  +    private final String path;
> > >>>>  +
> > >>>>  +    private ClassLoader classLoader;
> > >>>>  +
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Create a new resource using the current context class
> loader.
> > >>>>  +     *
> > >>>>  +     * @param path the resource path, not null
> > >>>>  +     * @see java.lang.ClassLoader#getResourceAsStream(String)
> > >>>>  +     */
> > >>>>  +    public ClassPathResource(String path) {
> > >>>>  +        this(path, (ClassLoader) null);
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Create a new resource using the given class loader.
> > >>>>  +     *
> > >>>>  +     * @param path        the resource path, not null
> > >>>>  +     * @param classLoader the class loader to load the resource
> > with,
> > >>>>  +     *                    or {@code null} for the current context
> > >>> class
> > >>>>  loader
> > >>>>  +     * @see ClassLoader#getResourceAsStream(String)
> > >>>>  +     */
> > >>>>  +    public ClassPathResource(String path, ClassLoader
> classLoader) {
> > >>>>  +        Objects.requireNonNull(path, "Path null");
> > >>>>  +        if (path.startsWith("/")) {
> > >>>>  +            path = path.substring(1);
> > >>>>  +        }
> > >>>>  +        this.path = path.trim();
> > >>>>  +        if(classLoader==null){
> > >>>>  +            classLoader =
> > Thread.currentThread().getContextClassLoader();
> > >>>>  +        }
> > >>>>  +        if(classLoader==null){
> > >>>>  +            classLoader = getClass().getClassLoader();
> > >>>>  +        }
> > >>>>  +        this.classLoader = classLoader;
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * @return the path for this resource.
> > >>>>  +     */
> > >>>>  +    public final String getPath() {
> > >>>>  +        return this.path;
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * @return the ClassLoader that this resource will be accessed
> > from.
> > >>>>  +     */
> > >>>>  +    public final ClassLoader getClassLoader() {
> > >>>>  +        return this.classLoader;
> > >>>>  +    }
> > >>>>  +
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Checks if the given resource is resolvable from the
> > configured
> > >>>>  classloader.
> > >>>>  +     *
> > >>>>  +     * @see java.lang.ClassLoader#getResource(String)
> > >>>>  +     */
> > >>>>  +    @Override
> > >>>>  +    public boolean exists() {
> > >>>>  +        return (resolveURL() != null);
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Resolves a URL for the underlying class path resource.
> > >>>>  +     *
> > >>>>  +     * @return the resolved URL, or {@code null}
> > >>>>  +     */
> > >>>>  +    protected URL resolveURL() {
> > >>>>  +        return this.classLoader.getResource(this.path);
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * This implementation opens an InputStream for the given
> class
> > path
> > >>>>  resource.
> > >>>>  +     *
> > >>>>  +     * @see java.lang.ClassLoader#getResourceAsStream(String)
> > >>>>  +     * @see java.lang.Class#getResourceAsStream(String)
> > >>>>  +     */
> > >>>>  +    @Override
> > >>>>  +    public InputStream getInputStream() throws IOException {
> > >>>>  +        InputStream is =
> > this.classLoader.getResourceAsStream(this.path);
> > >>>>  +        if (is == null) {
> > >>>>  +            throw new IOException(getName() + " does not
> > >>> exist");
> > >>>>  +        }
> > >>>>  +        return is;
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    @Override
> > >>>>  +    public URI toURI() throws IOException {
> > >>>>  +        try {
> > >>>>  +            return resolveURL().toURI();
> > >>>>  +        } catch (URISyntaxException e) {
> > >>>>  +            throw new IOException(e);
> > >>>>  +        }
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    @Override
> > >>>>  +    public long lastModified() throws IOException {
> > >>>>  +        return 0;
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * This implementation returns the name current the file that
> > this
> > >>> class
> > >>>>  path
> > >>>>  +     * resource refers to.
> > >>>>  +     */
> > >>>>  +    @Override
> > >>>>  +    public String getName() {
> > >>>>  +        return "classpath:"+path;
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * This implementation returns a description that includes the
> > class
> > >>> path
> > >>>>  location.
> > >>>>  +     */
> > >>>>  +    @Override
> > >>>>  +    public String toString() {
> > >>>>  +        return "ClassPathResource[" + path + ']';
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * This implementation compares the underlying class path
> > locations.
> > >>>>  +     */
> > >>>>  +    @Override
> > >>>>  +    public boolean equals(Object obj) {
> > >>>>  +        if (obj == this) {
> > >>>>  +            return true;
> > >>>>  +        }
> > >>>>  +        if (obj instanceof ClassPathResource) {
> > >>>>  +            ClassPathResource otherRes = (ClassPathResource) obj;
> > >>>>  +            return (this.path.equals(otherRes.path) &&
> > >>>>  +                    Objects.equals(this.classLoader,
> > >>> otherRes.classLoader));
> > >>>>  +        }
> > >>>>  +        return false;
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * This implementation returns the hash code current the
> > underlying
> > >>>>  +     * class path location.
> > >>>>  +     */
> > >>>>  +    @Override
> > >>>>  +    public int hashCode() {
> > >>>>  +        return getName().hashCode();
> > >>>>  +    }
> > >>>>  +
> > >>>>  +}
> > >>>>
> > >>>>
> > >>>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
> > >>>>
> > ----------------------------------------------------------------------
> > >>>>  diff --git
> > >>>>
> > >>>
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
> > >>>
> > >>>>
> > >>>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
> > >>>>  new file mode 100644
> > >>>>  index 0000000..eb56c1d
> > >>>>  --- /dev/null
> > >>>>  +++
> > >>>>
> > >>>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
> > >>>>  @@ -0,0 +1,93 @@
> > >>>>  +/*
> > >>>>  + * Licensed to the Apache Software Foundation (ASF) under one
> > >>>>  + * or more contributor license agreements.  See the NOTICE file
> > >>>>  + * distributed with this work for additional information
> > >>>>  + * regarding copyright ownership.  The ASF licenses this file
> > >>>>  + * to you under the Apache License, Version 2.0 (the
> > >>>>  + * "License"); you may not use this file except in compliance
> > >>>>  + * with the License.  You may obtain a copy of the License at
> > >>>>  + *
> > >>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
> > >>>>  + *
> > >>>>  + * Unless required by applicable law or agreed to in writing,
> > >>>>  + * software distributed under the License is distributed on an
> > >>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>>>  + * KIND, either express or implied.  See the License for the
> > >>>>  + * specific language governing permissions and limitations
> > >>>>  + * under the License.
> > >>>>  + */
> > >>>>  +package org.apache.tamaya.core.internal.resource;
> > >>>>  +
> > >>>>  +import org.apache.tamaya.core.resources.Resource;
> > >>>>  +import org.apache.tamaya.core.resources.ResourceLoader;
> > >>>>  +
> > >>>>  +import javax.annotation.Priority;
> > >>>>  +import java.io.File;
> > >>>>  +import java.net.URL;
> > >>>>  +import java.util.ArrayList;
> > >>>>  +import java.util.Collection;
> > >>>>  +import java.util.Enumeration;
> > >>>>  +import java.util.List;
> > >>>>  +import java.util.logging.Logger;
> > >>>>  +
> > >>>>  +/**
> > >>>>  + * Simple default implementation of the resource loader, which
> does
> > only
> > >>>>  support direct references to files.
> > >>>>  + */
> > >>>>  +@Priority(0)
> > >>>>  +public class DefaultResourceLoader implements ResourceLoader {
> > >>>>  +
> > >>>>  +    private static final Logger LOG =
> > >>>>  Logger.getLogger(DefaultResourceLoader.class.getName());
> > >>>>  +
> > >>>>  +    @Override
> > >>>>  +    public List<Resource> getResources(ClassLoader classLoader,
> > >>>>  Collection<String> expressions) {
> > >>>>  +        List<Resource> resources = new ArrayList<>();
> > >>>>  +        for (String expression : expressions) {
> > >>>>  +            if (tryClassPath(classLoader, expression, resources)
> ||
> > >>>>  tryFile(expression, resources) ||
> > >>>>  +                    tryURL(expression, resources)) {
> > >>>>  +                continue;
> > >>>>  +            }
> > >>>>  +            LOG.warning("Failed to resolve resource: " +
> > >>> expression);
> > >>>>  +        }
> > >>>>  +        return resources;
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    private boolean tryClassPath(ClassLoader classLoader, String
> > >>> expression,
> > >>>>  List<Resource> resources) {
> > >>>>  +        try {
> > >>>>  +            Enumeration<URL> urls =
> > >>> classLoader.getResources(expression);
> > >>>>  +            while (urls.hasMoreElements()) {
> > >>>>  +                URL url = urls.nextElement();
> > >>>>  +                resources.add(new URLResource(url));
> > >>>>  +            }
> > >>>>  +            return !resources.isEmpty();
> > >>>>  +        } catch (Exception e) {
> > >>>>  +            LOG.finest(() -> "Failed to load resource from CP:
> > >>> " +
> > >>>>  expression);
> > >>>>  +        }
> > >>>>  +        return false;
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    private boolean tryFile(String expression, List<Resource>
> > >>> resources)
> > >>>>  {
> > >>>>  +        try {
> > >>>>  +            File file = new File(expression);
> > >>>>  +            if (file.exists()) {
> > >>>>  +                resources.add(new FileResource(file));
> > >>>>  +                return true;
> > >>>>  +            }
> > >>>>  +        } catch (Exception e) {
> > >>>>  +            LOG.finest(() -> "Failed to load resource from file:
> > >>> "
> > >>>>  + expression);
> > >>>>  +        }
> > >>>>  +        return false;
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    private boolean tryURL(String expression, List<Resource>
> > >>> resources)
> > >>>>  {
> > >>>>  +        try {
> > >>>>  +            URL url = new URL(expression);
> > >>>>  +            resources.add(new URLResource(url));
> > >>>>  +            return true;
> > >>>>  +        } catch (Exception e) {
> > >>>>  +            LOG.finest(() -> "Failed to load resource from file:
> > >>> "
> > >>>>  + expression);
> > >>>>  +        }
> > >>>>  +        return false;
> > >>>>  +
> > >>>>  +    }
> > >>>>  +
> > >>>>  +}
> > >>>>
> > >>>>
> > >>>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
> > >>>>
> > ----------------------------------------------------------------------
> > >>>>  diff --git
> > >>>>
> > >>>
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
> > >>>>
> > >>>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
> > >>>>  new file mode 100644
> > >>>>  index 0000000..e0096e5
> > >>>>  --- /dev/null
> > >>>>  +++
> > >>>>
> > >>>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
> > >>>>  @@ -0,0 +1,162 @@
> > >>>>  +/*
> > >>>>  + * Licensed to the Apache Software Foundation (ASF) under one
> > >>>>  + * or more contributor license agreements.  See the NOTICE file
> > >>>>  + * distributed with this work for additional information
> > >>>>  + * regarding copyright ownership.  The ASF licenses this file
> > >>>>  + * to you under the Apache License, Version 2.0 (the
> > >>>>  + * "License"); you may not use this file except in compliance
> > >>>>  + * with the License.  You may obtain a copy of the License at
> > >>>>  + *
> > >>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
> > >>>>  + *
> > >>>>  + * Unless required by applicable law or agreed to in writing,
> > >>>>  + * software distributed under the License is distributed on an
> > >>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>>>  + * KIND, either express or implied.  See the License for the
> > >>>>  + * specific language governing permissions and limitations
> > >>>>  + * under the License.
> > >>>>  + */
> > >>>>  +package org.apache.tamaya.core.internal.resource;
> > >>>>  +
> > >>>>  +import org.apache.tamaya.core.resources.Resource;
> > >>>>  +
> > >>>>  +import java.io.File;
> > >>>>  +import java.io.FileInputStream;
> > >>>>  +import java.io.IOException;
> > >>>>  +import java.io.InputStream;
> > >>>>  +import java.net.URI;
> > >>>>  +import java.util.Objects;
> > >>>>  +
> > >>>>  +/**
> > >>>>  + * Implementation of {@link
> > >>> org.apache.tamaya.core.resources.Resource} to
> > >>>>  be loaded from a file.
> > >>>>  + * @see java.io.File
> > >>>>  + */
> > >>>>  +public class FileResource implements Resource {
> > >>>>  +
> > >>>>  +    private final File file;
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Creates a new instance.
> > >>>>  +     *
> > >>>>  +     * @param file a File, not null.
> > >>>>  +     */
> > >>>>  +    public FileResource(File file) {
> > >>>>  +        this.file = Objects.requireNonNull(file, "File must not be
> > >>>>  null");
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Crreates a new instance.
> > >>>>  +     *
> > >>>>  +     * @param filePath a file path
> > >>>>  +     */
> > >>>>  +    public FileResource(String filePath) {
> > >>>>  +        Objects.requireNonNull(filePath, "Path must not be
> > >>> null");
> > >>>>  +        this.file = new File(filePath);
> > >>>>  +    }
> > >>>>  +
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Get the file path for this resource.
> > >>>>  +     */
> > >>>>  +    public final String getPath() {
> > >>>>  +        return this.file.getPath();
> > >>>>  +    }
> > >>>>  +
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * This implementation returns whether the underlying file
> > exists.
> > >>>>  +     *
> > >>>>  +     * @see java.io.File#exists()
> > >>>>  +     */
> > >>>>  +    @Override
> > >>>>  +    public boolean exists() {
> > >>>>  +        return this.file.exists();
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * This implementation checks whether the underlying file is
> > marked as
> > >>>
> > >>>>  readable
> > >>>>  +     * (and corresponds to an actual file with content, not to a
> > >>> directory).
> > >>>>  +     *
> > >>>>  +     * @see java.io.File#canRead()
> > >>>>  +     * @see java.io.File#isDirectory()
> > >>>>  +     */
> > >>>>  +    @Override
> > >>>>  +    public boolean isAccessible() {
> > >>>>  +        return (this.file.canRead() && !this.file.isDirectory());
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * This implementation opens a FileInputStream for the
> > underlying
> > >>> file.
> > >>>>  +     *
> > >>>>  +     * @see java.io.FileInputStream
> > >>>>  +     */
> > >>>>  +    @Override
> > >>>>  +    public InputStream getInputStream() throws IOException {
> > >>>>  +        return new FileInputStream(this.file);
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * This implementation returns a URI for the underlying file.
> > >>>>  +     *
> > >>>>  +     * @see java.io.File#toURI()
> > >>>>  +     */
> > >>>>  +    @Override
> > >>>>  +    public URI toURI() throws IOException {
> > >>>>  +        return this.file.toURI();
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Returns the underlying File's length.
> > >>>>  +     */
> > >>>>  +    @Override
> > >>>>  +    public long length() throws IOException {
> > >>>>  +        return this.file.length();
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    @Override
> > >>>>  +    public long lastModified() throws IOException {
> > >>>>  +        return file.lastModified();
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Returns the name of the current file.
> > >>>>  +     *
> > >>>>  +     * @see java.io.File#getName()
> > >>>>  +     */
> > >>>>  +    @Override
> > >>>>  +    public String getName() {
> > >>>>  +        return this.file.getName();
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Returns a description that includes the absolute
> > >>>>  +     * path of the current file.
> > >>>>  +     *
> > >>>>  +     * @see java.io.File#getAbsolutePath()
> > >>>>  +     */
> > >>>>  +    @Override
> > >>>>  +    public String toString() {
> > >>>>  +        return "File [" + this.file.getAbsolutePath() +
> > >>>>  "]";
> > >>>>  +    }
> > >>>>  +
> > >>>>  +
> > >>>>  +    // implementation current WritableResource
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Compares the underlying Files.
> > >>>>  +     */
> > >>>>  +    @Override
> > >>>>  +    public boolean equals(Object obj) {
> > >>>>  +        return (obj == this ||
> > >>>>  +                (obj instanceof FileResource &&
> > >>>>  this.file.equals(((FileResource) obj).file)));
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Returns hash code current the underlying File reference.
> > >>>>  +     */
> > >>>>  +    @Override
> > >>>>  +    public int hashCode() {
> > >>>>  +        return this.file.hashCode();
> > >>>>  +    }
> > >>>>  +
> > >>>>  +}
> > >>>>
> > >>>>
> > >>>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
> > >>>>
> > ----------------------------------------------------------------------
> > >>>>  diff --git
> > >>>>
> > >>>
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
> > >>>
> > >>>>
> > >>>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
> > >>>>  new file mode 100644
> > >>>>  index 0000000..09510b4
> > >>>>  --- /dev/null
> > >>>>  +++
> > >>>>
> > >>>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
> > >>>>  @@ -0,0 +1,117 @@
> > >>>>  +/*
> > >>>>  + * Licensed to the Apache Software Foundation (ASF) under one
> > >>>>  + * or more contributor license agreements.  See the NOTICE file
> > >>>>  + * distributed with this work for additional information
> > >>>>  + * regarding copyright ownership.  The ASF licenses this file
> > >>>>  + * to you under the Apache License, Version 2.0 (the
> > >>>>  + * "License"); you may not use this file except in compliance
> > >>>>  + * with the License.  You may obtain a copy of the License at
> > >>>>  + *
> > >>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
> > >>>>  + *
> > >>>>  + * Unless required by applicable law or agreed to in writing,
> > >>>>  + * software distributed under the License is distributed on an
> > >>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>>>  + * KIND, either express or implied.  See the License for the
> > >>>>  + * specific language governing permissions and limitations
> > >>>>  + * under the License.
> > >>>>  + */
> > >>>>  +package org.apache.tamaya.core.internal.resource;
> > >>>>  +
> > >>>>  +import org.apache.tamaya.core.resources.Resource;
> > >>>>  +
> > >>>>  +import java.io.IOException;
> > >>>>  +import java.io.InputStream;
> > >>>>  +import java.net.URI;
> > >>>>  +import java.util.Objects;
> > >>>>  +
> > >>>>  +/**
> > >>>>  + * Simple Resource encapsulating an InputStream.
> > >>>>  + */
> > >>>>  +public class InputStreamResource implements Resource {
> > >>>>  +
> > >>>>  +    /** The InputStream. */
> > >>>>  +    private final InputStream inputStream;
> > >>>>  +    /** The read flag. */
> > >>>>  +    private boolean read = false;
> > >>>>  +    /** The name of the resource. */
> > >>>>  +    private String name;
> > >>>>  +
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Create a new InputStreamResource.
> > >>>>  +     *
> > >>>>  +     * @param inputStream the InputStream to use
> > >>>>  +     */
> > >>>>  +    public InputStreamResource(InputStream inputStream) {
> > >>>>  +        this(inputStream, "InputStream:");
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Create a new InputStreamResource.
> > >>>>  +     *
> > >>>>  +     * @param inputStream the InputStream to use
> > >>>>  +     * @param name where the InputStream comes from
> > >>>>  +     */
> > >>>>  +    public InputStreamResource(InputStream inputStream, String
> name)
> > >>> {
> > >>>>  +        this.inputStream = Objects.requireNonNull(inputStream);
> > >>>>  +        this.name = (name != null ? name : "InputStream");
> > >>>>  +    }
> > >>>>  +
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * This implementation always returns {@code true}.
> > >>>>  +     */
> > >>>>  +    @Override
> > >>>>  +    public boolean exists() {
> > >>>>  +        return true;
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    @Override
> > >>>>  +    public URI toURI() throws IOException {
> > >>>>  +        throw new IOException("URI not available.");
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    @Override
> > >>>>  +    public long lastModified() throws IOException {
> > >>>>  +        throw new IOException("lastModified not available.");
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Accesses the input stream. Hereby the input stream can only
> > >>> accessed
> > >>>>  once.
> > >>>>  +     */
> > >>>>  +    @Override
> > >>>>  +    public InputStream getInputStream() throws IOException {
> > >>>>  +        if (this.read) {
> > >>>>  +            throw new IllegalStateException("InputStream can only
> be
> > >>> read
> > >>>>  once!");
> > >>>>  +        }
> > >>>>  +        this.read = true;
> > >>>>  +        return this.inputStream;
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * This implementation returns the passed-in description, if
> > any.
> > >>>>  +     */
> > >>>>  +    public String toString() {
> > >>>>  +        return this.name != null ? this.name : super.toString();
> > >>>>  +    }
> > >>>>  +
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Compares the underlying InputStream.
> > >>>>  +     */
> > >>>>  +    @Override
> > >>>>  +    public boolean equals(Object obj) {
> > >>>>  +        return (obj == this ||
> > >>>>  +                (obj instanceof InputStreamResource &&
> > >>>>  ((InputStreamResource) obj).inputStream.equals(this.inputStream)));
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * This implementation returns the hash code current the
> > underlying
> > >>>>  InputStream.
> > >>>>  +     */
> > >>>>  +    @Override
> > >>>>  +    public int hashCode() {
> > >>>>  +        return this.inputStream.hashCode();
> > >>>>  +    }
> > >>>>  +
> > >>>>  +}
> > >>>>
> > >>>>
> > >>>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
> > >>>>
> > ----------------------------------------------------------------------
> > >>>>  diff --git
> > >>>>
> > >>>
> >
> a/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
> > >>>>
> > >>>
> >
> b/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
> > >>>>  new file mode 100644
> > >>>>  index 0000000..4da6c53
> > >>>>  --- /dev/null
> > >>>>  +++
> > >>>>
> > >>>
> >
> b/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
> > >>>>  @@ -0,0 +1,37 @@
> > >>>>  +/*
> > >>>>  + * Licensed to the Apache Software Foundation (ASF) under one
> > >>>>  + * or more contributor license agreements.  See the NOTICE file
> > >>>>  + * distributed with this work for additional information
> > >>>>  + * regarding copyright ownership.  The ASF licenses this file
> > >>>>  + * to you under the Apache License, Version 2.0 (the
> > >>>>  + * "License"); you may not use this file except in compliance
> > >>>>  + * with the License.  You may obtain a copy of the License at
> > >>>>  + *
> > >>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
> > >>>>  + *
> > >>>>  + * Unless required by applicable law or agreed to in writing,
> > >>>>  + * software distributed under the License is distributed on an
> > >>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>>>  + * KIND, either express or implied.  See the License for the
> > >>>>  + * specific language governing permissions and limitations
> > >>>>  + * under the License.
> > >>>>  + */
> > >>>>  +package org.apache.tamaya.core.resources;
> > >>>>  +
> > >>>>  +import java.io.IOException;
> > >>>>  +import java.io.InputStream;
> > >>>>  +
> > >>>>  +/**
> > >>>>  + * Simple interface for a component that provides data based on an
> > >>> InputStream.
> > >>>>  + */
> > >>>>  +@FunctionalInterface
> > >>>>  +public interface InputStreamSupplier {
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Access the input stream.
> > >>>>  +     * @return the input stream for use.
> > >>>>  +     * @throws IOException i the input stream could not be
> obtained.
> > >>>>  +     */
> > >>>>  +    InputStream getInputStream() throws IOException;
> > >>>>  +
> > >>>>  +}
> > >>>>
> > >>>>
> > >>>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
> > >>>>
> > ----------------------------------------------------------------------
> > >>>>  diff --git
> > >>> a/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
> > >>>>  b/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
> > >>>>  new file mode 100644
> > >>>>  index 0000000..31c679d
> > >>>>  --- /dev/null
> > >>>>  +++
> > b/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
> > >>>>  @@ -0,0 +1,115 @@
> > >>>>  +/*
> > >>>>  + * Licensed to the Apache Software Foundation (ASF) under one
> > >>>>  + * or more contributor license agreements.  See the NOTICE file
> > >>>>  + * distributed with this work for additional information
> > >>>>  + * regarding copyright ownership.  The ASF licenses this file
> > >>>>  + * to you under the Apache License, Version 2.0 (the
> > >>>>  + * "License"); you may not use this file except in compliance
> > >>>>  + * with the License.  You may obtain a copy of the License at
> > >>>>  + *
> > >>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
> > >>>>  + *
> > >>>>  + * Unless required by applicable law or agreed to in writing,
> > >>>>  + * software distributed under the License is distributed on an
> > >>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>>>  + * KIND, either express or implied.  See the License for the
> > >>>>  + * specific language governing permissions and limitations
> > >>>>  + * under the License.
> > >>>>  + */
> > >>>>  +package org.apache.tamaya.core.resources;
> > >>>>  +
> > >>>>  +import java.io.File;
> > >>>>  +import java.io.IOException;
> > >>>>  +import java.io.InputStream;
> > >>>>  +import java.net.URI;
> > >>>>  +import java.net.URL;
> > >>>>  +import java.util.Objects;
> > >>>>  +
> > >>>>  +/**
> > >>>>  + * Interface for an abstract resource. The effective resource
> > >>> implementation
> > >>>>  can be completely arbitrary.
> > >>>>  + * By default files, classpath resources and URLs are supported,
> but
> > >>> alternate
> > >>>>  implementations are possible.
> > >>>>  + *
> > >>>>  + * @see #getInputStream()
> > >>>>  + * @see #toURI()
> > >>>>  + */
> > >>>>  +public interface Resource extends InputStreamSupplier {
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Return whether this resource actually exists. Depending on
> > the
> > >>> resource
> > >>>>  this can delegate to
> > >>>>  +     * {@link java.io.File#exists()} or whatever may be
> appropriate
> > >>> to
> > >>>>  check accessibility of the resource.
> > >>>>  +     */
> > >>>>  +    default boolean exists() {
> > >>>>  +        // Try to open a file first, if that fails try to open the
> > >>> stream...
> > >>>>  +        try {
> > >>>>  +            return new File(toURI()).exists();
> > >>>>  +        } catch (IOException ex) {
> > >>>>  +            // Fallback
> > >>>>  +            try {
> > >>>>  +                InputStream is = getInputStream();
> > >>>>  +                is.close();
> > >>>>  +                return true;
> > >>>>  +            } catch (Exception e) {
> > >>>>  +                // ignore, just return false for non existing
> > >>>>  +                return false;
> > >>>>  +            }
> > >>>>  +        }
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Checks whether the resource is accessible, meaning {@link
> > >>>>  #getInputStream()} should return a InputStream for reading the
> > >>>>  +     * resource's content.
> > >>>>  +     *
> > >>>>  +     * @see #getInputStream()
> > >>>>  +     */
> > >>>>  +    default boolean isAccessible() {
> > >>>>  +        return true;
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Returns the resource as an URI.
> > >>>>  +     *
> > >>>>  +     * @throws IOException if the resource cannot be resolved as
> > URI.
> > >>>>  +     */
> > >>>>  +    URI toURI() throws IOException;
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Determines the length for this resource.
> > >>>>  +     *
> > >>>>  +     * @throws IOException if the resource is not readable.
> > >>>>  +     */
> > >>>>  +    default long length() throws IOException {
> > >>>>  +        try(InputStream is = this.getInputStream();) {
> > >>>>  +            Objects.requireNonNull(is, "resource not
> > >>> available");
> > >>>>  +            long length = 0;
> > >>>>  +            byte[] buf = new byte[256];
> > >>>>  +            int bytesRead;
> > >>>>  +            while ((bytesRead = is.read(buf)) > 0) {
> > >>>>  +                length += bytesRead;
> > >>>>  +            }
> > >>>>  +            return length;
> > >>>>  +        }
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Determine the last-modified timestamp for a resource, as
> UTC
> > ms
> > >>>>  timestamp
> > >>>>  +     *
> > >>>>  +     * @throws IOException if the resource is not accessible.
> > >>>>  +     */
> > >>>>  +    default long lastModified() throws IOException{
> > >>>>  +        return new File(toURI()).lastModified();
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Get a name for the resource. The name should be identifying
> > the
> > >>> resource
> > >>>>  and also
> > >>>>  +     * never change, so it must be eligible for hashcode/equals
> > >>>>  implementations.
> > >>>>  +     */
> > >>>>  +    default String getName() {
> > >>>>  +        try {
> > >>>>  +            return toURI().toString();
> > >>>>  +        } catch (Exception e) {
> > >>>>  +            return toString();
> > >>>>  +        }
> > >>>>  +    }
> > >>>>  +
> > >>>>  +
> > >>>>  +}
> > >>>>  \ No newline at end of file
> > >>>>
> > >>>>
> > >>>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
> > >>>>
> > ----------------------------------------------------------------------
> > >>>>  diff --git
> > >>>>
> > a/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
> > >>>>
> > b/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
> > >>>>  new file mode 100644
> > >>>>  index 0000000..5aff10a
> > >>>>  --- /dev/null
> > >>>>  +++
> > >>>
> > b/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
> > >>>>  @@ -0,0 +1,91 @@
> > >>>>  +/*
> > >>>>  + * Licensed to the Apache Software Foundation (ASF) under one
> > >>>>  + * or more contributor license agreements.  See the NOTICE file
> > >>>>  + * distributed with this work for additional information
> > >>>>  + * regarding copyright ownership.  The ASF licenses this file
> > >>>>  + * to you under the Apache License, Version 2.0 (the
> > >>>>  + * "License"); you may not use this file except in compliance
> > >>>>  + * with the License.  You may obtain a copy of the License at
> > >>>>  + *
> > >>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
> > >>>>  + *
> > >>>>  + * Unless required by applicable law or agreed to in writing,
> > >>>>  + * software distributed under the License is distributed on an
> > >>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>>>  + * KIND, either express or implied.  See the License for the
> > >>>>  + * specific language governing permissions and limitations
> > >>>>  + * under the License.
> > >>>>  + */
> > >>>>  +package org.apache.tamaya.core.resources;
> > >>>>  +
> > >>>>  +import java.util.Arrays;
> > >>>>  +import java.util.Collection;
> > >>>>  +import java.util.List;
> > >>>>  +
> > >>>>  +/**
> > >>>>  + * Interface to be implemented by modules. By default only direct
> > >>> file/resource
> > >>>>  resolution is supported, whereas
> > >>>>  + * extension modules may add functionality to perform ant styled
> > pattern
> > >>>>  resolution of resources.
> > >>>>  + */
> > >>>>  +public interface ResourceLoader {
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Resolves resource expressions to a list of {@link
> > >>>>  org.apache.tamaya.core.resources.Resource}s. Hereby
> > >>>>  +     * the ordering of resources matches the input of the resolved
> > >>> expressions.
> > >>>>  Nevertheless be aware that
> > >>>>  +     * there is no determined ordering of resources located
> within a
> > >>>>  classloader.
> > >>>>  +     *
> > >>>>  +     * @param expressions the expressions to be resolved, not
> empty.
> > >>>>  +     * @return the corresponding collection of current {@link
> > >>>>  org.apache.tamaya.core.resources.Resource}s found, never
> > >>>>  +     * null.
> > >>>>  +     * .
> > >>>>  +     */
> > >>>>  +    default Collection<Resource>
> > >>> getResources(Collection<String>
> > >>>>  expressions) {
> > >>>>  +        ClassLoader cl =
> > Thread.currentThread().getContextClassLoader();
> > >>>>  +        if (cl == null) {
> > >>>>  +            cl = getClass().getClassLoader();
> > >>>>  +        }
> > >>>>  +        return getResources(cl, expressions);
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Resolves resource expressions to a list of {@link
> > >>>>  org.apache.tamaya.core.resources.Resource}s. Hereby
> > >>>>  +     * the ordering of resources matches the input of the resolved
> > >>> expressions.
> > >>>>  Nevertheless be aware that
> > >>>>  +     * there is no determined ordering of resources located
> within a
> > >>>>  classloader.
> > >>>>  +     *
> > >>>>  +     * @param expressions the expressions to be resolved, not
> empty.
> > >>>>  +     * @return the corresponding collection of current {@link
> > >>>>  org.apache.tamaya.core.resources.Resource}s found, never
> > >>>>  +     * null.
> > >>>>  +     * .
> > >>>>  +     */
> > >>>>  +    default Collection<Resource> getResources(String...
> expressions)
> > >>>
> > >>>>  {
> > >>>>  +        return getResources(Arrays.asList(expressions));
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Resolves resource expressions to a list of {@link
> > >>>>  org.apache.tamaya.core.resources.Resource}s, considerubg
> > >>>>  +     * the given classloader for classloader dependent resources.
> > Hereby
> > >>>>  +     * the ordering of resources matches the input of the resolved
> > >>> expressions.
> > >>>>  Nevertheless be aware that
> > >>>>  +     * there is no determined ordering of resources located
> within a
> > >>>>  classloader.
> > >>>>  +     *
> > >>>>  +     * @param expressions the expressions to be resolved, not
> empty.
> > >>>>  +     * @return the corresponding collection of current {@link
> > >>>>  org.apache.tamaya.core.resources.Resource}s found, never
> > >>>>  +     * null.
> > >>>>  +     * .
> > >>>>  +     */
> > >>>>  +    default Collection<Resource> getResources(ClassLoader
> > >>> classLoader,
> > >>>>  String... expressions){
> > >>>>  +        return getResources(classLoader,
> > Arrays.asList(expressions));
> > >>>>  +    }
> > >>>>  +
> > >>>>  +    /**
> > >>>>  +     * Resolves resource expressions to a list of {@link
> > >>>>  org.apache.tamaya.core.resources.Resource}s, considerubg
> > >>>>  +     * the given classloader for classloader dependent resources.
> > Hereby
> > >>>>  +     * the ordering of resources matches the input of the resolved
> > >>> expressions.
> > >>>>  Nevertheless be aware that
> > >>>>  +     * there is no determined ordering of resources located
> within a
> > >>>>  classloader.
> > >>>>  +     *
> > >>>>  +     * @param expressions the expressions to be resolved, not
> empty.
> > >>>>  +     * @return the corresponding collection of current {@link
> > >>>>  org.apache.tamaya.core.resources.Resource}s found, never
> > >>>>  +     * null.
> > >>>>  +     * .
> > >>>>  +     */
> > >>>>  +    Collection<Resource> getResources(ClassLoader classLoader,
> > >>>>  Collection<String> expressions);
> > >>>>  +
> > >>>>  +}
> > >>>>
> > >>>>
> > >>>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> > >>>>
> > ----------------------------------------------------------------------
> > >>>>  diff --git
> > >>> a/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> > >>>>  b/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> > >>>>  index be1eadb..9c7b894 100644
> > >>>>  ---
> > a/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> > >>>>  +++
> > b/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> > >>>>  @@ -41,6 +41,12 @@ public class ConfigurationTest {
> > >>>>           assertEquals("Lukas",
> > >>>>  Configuration.current().get("name3").get());  // oderridden
> > >>> default
> > >>>>           assertEquals("Sereina",
> > >>>>  Configuration.current().get("name4").get()); // final only
> > >>>>           assertEquals("Benjamin",
> > >>>>  Configuration.current().get("name5").get()); // final only
> > >>>>  +
> > >>>>  +        System.out.println("name : " +
> > >>>>  Configuration.current().get("name").get());
> > >>>>  +        System.out.println("name2: " +
> > >>>>  Configuration.current().get("name2").get());
> > >>>>  +        System.out.println("name3: " +
> > >>>>  Configuration.current().get("name3").get());
> > >>>>  +        System.out.println("name4: " +
> > >>>>  Configuration.current().get("name4").get());
> > >>>>  +        System.out.println("name5: " +
> > >>>>  Configuration.current().get("name5").get());
> > >>>>       }
> > >>>>
> > >>>>
> > >>>>
> > >>>>
> > >>>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
> > >>>>
> > ----------------------------------------------------------------------
> > >>>>  diff --git
> > >>>>
> > >>>
> >
> a/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
> > >>>
> > >>>>
> > >>>
> >
> b/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
> > >>>>  deleted file mode 100644
> > >>>>  index 51cc2dc..0000000
> > >>>>  ---
> > >>>>
> > >>>
> >
> a/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
> > >>>>  +++ /dev/null
> > >>>>  @@ -1,70 +0,0 @@
> > >>>>  -/*
> > >>>>  - * Licensed to the Apache Software Foundation (ASF) under one
> > >>>>  - * or more contributor license agreements.  See the NOTICE file
> > >>>>  - * distributed with this work for additional information
> > >>>>  - * regarding copyright ownership.  The ASF licenses this file
> > >>>>  - * to you under the Apache License, Version 2.0 (the
> > >>>>  - * "License"); you may not use this file except in compliance
> > >>>>  - * with the License.  You may obtain a copy of the License at
> > >>>>  - *
> > >>>>  - * http://www.apache.org/licenses/LICENSE-2.0
> > >>>>  - *
> > >>>>  - * Unless required by applicable law or agreed to in writing,
> > >>>>  - * software distributed under the License is distributed on an
> > >>>>  - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>>>  - * KIND, either express or implied.  See the License for the
> > >>>>  - * specific language governing permissions and limitations
> > >>>>  - * under the License.
> > >>>>  - */
> > >>>>  -package org.apache.tamaya.core.test.propertysource;
> > >>>>  -
> > >>>>  -import org.apache.tamaya.core.propertysource.DefaultOrdinal;
> > >>>>  -import
> > org.apache.tamaya.core.propertysource.EnvironmentPropertySource;
> > >>>>  -import org.junit.Assert;
> > >>>>  -import org.junit.Test;
> > >>>>  -
> > >>>>  -import java.util.Map;
> > >>>>  -import java.util.Optional;
> > >>>>  -
> > >>>>  -public class EnvironmentPropertySourceTest {
> > >>>>  -
> > >>>>  -    private EnvironmentPropertySource propertySource = new
> > >>>>  EnvironmentPropertySource();
> > >>>>  -
> > >>>>  -
> > >>>>  -    @Test
> > >>>>  -    public void testGetOrdinal() {
> > >>>>  -        Assert.assertEquals(DefaultOrdinal.ENVIRONMENT_PROPERTIES,
> > >>>>  propertySource.getOrdinal());
> > >>>>  -    }
> > >>>>  -
> > >>>>  -    @Test
> > >>>>  -    public void testGet() {
> > >>>>  -        String environmentPropertyToCheck =
> > >>>>  System.getenv().keySet().iterator().next();
> > >>>>  -
> > >>>>  -        Optional<String> value =
> > >>>>  propertySource.get(environmentPropertyToCheck);
> > >>>>  -        Assert.assertTrue(value.isPresent());
> > >>>>  -
> > Assert.assertEquals(System.getenv(environmentPropertyToCheck),
> > >>>>  value.get());
> > >>>>  -    }
> > >>>>  -
> > >>>>  -    @Test
> > >>>>  -    public void testGetProperties() {
> > >>>>  -        Map<String, String> environmentProperties =
> System.getenv();
> > >>>>  -
> > >>>>  -        Assert.assertEquals(environmentProperties.size(),
> > >>>>  propertySource.getProperties().size());
> > >>>>  -
> > >>>>  -        for (Map.Entry<String, String> propertySourceEntry :
> > >>>>  propertySource.getProperties().entrySet()) {
> > >>>>  -            Assert.assertEquals("Entry values for key '" +
> > >>>>  propertySourceEntry.getKey() + "' do not match",
> > >>>>  -
> > >>>>  environmentProperties.get(propertySourceEntry.getKey()),
> > >>>>  propertySourceEntry.getValue());
> > >>>>  -        }
> > >>>>  -
> > >>>>  -        // modification is not allowed
> > >>>>  -        try {
> > >>>>  -            propertySource.getProperties().put("add.new.keys",
> > >>>>  "must throw exception");
> > >>>>  -
> > Assert.fail(UnsupportedOperationException.class.getName() +
> > >>> "
> > >>>>  expected");
> > >>>>  -        }
> > >>>>  -        catch (UnsupportedOperationException e) {
> > >>>>  -            // expected -> all is fine
> > >>>>  -        }
> > >>>>  -    }
> > >>>>  -
> > >>>>  -
> > >>>>  -}
> > >>>>
> > >>>>
> > >>>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
> > >>>>
> > ----------------------------------------------------------------------
> > >>>>  diff --git
> > >>>>
> > >>>
> >
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
> > >>>
> > >>>>
> > >>>
> >
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
> > >>>>  new file mode 100644
> > >>>>  index 0000000..5fa90b1
> > >>>>  --- /dev/null
> > >>>>  +++
> > >>>>
> > >>>
> >
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
> > >>>>  @@ -0,0 +1,32 @@
> > >>>>  +/*
> > >>>>  + * Licensed to the Apache Software Foundation (ASF) under one
> > >>>>  + * or more contributor license agreements.  See the NOTICE file
> > >>>>  + * distributed with this work for additional information
> > >>>>  + * regarding copyright ownership.  The ASF licenses this file
> > >>>>  + * to you under the Apache License, Version 2.0 (the
> > >>>>  + * "License"); you may not use this file except in compliance
> > >>>>  + * with the License.  You may obtain a copy of the License at
> > >>>>  + *
> > >>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
> > >>>>  + *
> > >>>>  + * Unless required by applicable law or agreed to in writing,
> > >>>>  + * software distributed under the License is distributed on an
> > >>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>>>  + * KIND, either express or implied.  See the License for the
> > >>>>  + * specific language governing permissions and limitations
> > >>>>  + * under the License.
> > >>>>  + */
> > >>>>  +package org.apache.tamaya.core.testdata;
> > >>>>  +
> > >>>>  +import org.apache.tamaya.core.PathBasedPropertySourceProvider;
> > >>>>  +import org.apache.tamaya.core.formats.PropertiesFormat;
> > >>>>  +
> > >>>>  +/**
> > >>>>  + * Test provider reading properties from
> > >>> classpath:cfg/defaults/**.properties.
> > >>>>  + */
> > >>>>  +public class TestPropertyDefaultSourceProvider extends
> > >>>>  PathBasedPropertySourceProvider{
> > >>>>  +
> > >>>>  +    public TestPropertyDefaultSourceProvider() {
> > >>>>  +        super("default-testdata-properties", new
> > >>>>  PropertiesFormat(100), "classpath:cfg/defaults/**/*.properties");
> > >>>>  +    }
> > >>>>  +}
> > >>>>
> > >>>>
> > >>>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
> > >>>>
> > ----------------------------------------------------------------------
> > >>>>  diff --git
> > >>>>
> > >>>
> >
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
> > >>>>
> > >>>
> >
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
> > >>>>  deleted file mode 100644
> > >>>>  index d1314aa..0000000
> > >>>>  ---
> > >>>
> >
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
> > >>>>  +++ /dev/null
> > >>>>  @@ -1,55 +0,0 @@
> > >>>>  -/*
> > >>>>  - * Licensed to the Apache Software Foundation (ASF) under one
> > >>>>  - * or more contributor license agreements.  See the NOTICE file
> > >>>>  - * distributed with this work for additional information
> > >>>>  - * regarding copyright ownership.  The ASF licenses this file
> > >>>>  - * to you under the Apache License, Version 2.0 (the
> > >>>>  - * "License"); you may not use this file except in compliance
> > >>>>  - * with the License.  You may obtain a copy of the License at
> > >>>>  - *
> > >>>>  - *  http://www.apache.org/licenses/LICENSE-2.0
> > >>>>  - *
> > >>>>  - * Unless required by applicable law or agreed to in writing,
> > >>>>  - * software distributed under the License is distributed on an
> > >>>>  - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>>>  - * KIND, either express or implied.  See the License for the
> > >>>>  - * specific language governing permissions and limitations
> > >>>>  - * under the License.
> > >>>>  - */
> > >>>>  -package org.apache.tamaya.core.testdata;
> > >>>>  -
> > >>>>  -import java.util.HashMap;
> > >>>>  -import java.util.Map;
> > >>>>  -
> > >>>>  -import org.apache.tamaya.core.propertysource.BasePropertySource;
> > >>>>  -
> > >>>>  -/**
> > >>>>  - * Test provider reading properties from
> > >>> classpath:cfg/final/**.properties.
> > >>>>  - */
> > >>>>  -public class TestPropertySource extends BasePropertySource {
> > >>>>  -
> > >>>>  -    private static final Map<String, String> VALUES;
> > >>>>  -    static {
> > >>>>  -        VALUES = new HashMap<String, String>();
> > >>>>  -        VALUES.put("name", "Robin");
> > >>>>  -        VALUES.put("name2", "Sabine");
> > >>>>  -        VALUES.put("name3", "Lukas");
> > >>>>  -        VALUES.put("name4", "Sereina");
> > >>>>  -        VALUES.put("name5", "Benjamin");
> > >>>>  -    }
> > >>>>  -
> > >>>>  -
> > >>>>  -    public TestPropertySource() {
> > >>>>  -        initialzeOrdinal(100);
> > >>>>  -    }
> > >>>>  -
> > >>>>  -    @Override
> > >>>>  -    public String getName() {
> > >>>>  -        return "TestPropertySource";
> > >>>>  -    }
> > >>>>  -
> > >>>>  -    @Override
> > >>>>  -    public Map<String, String> getProperties() {
> > >>>>  -        return VALUES;
> > >>>>  -    }
> > >>>>  -}
> > >>>>
> > >>>>
> > >>>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
> > >>>>
> > ----------------------------------------------------------------------
> > >>>>  diff --git
> > >>>>
> > >>>
> >
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
> > >>>
> > >>>>
> > >>>
> >
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
> > >>>>  new file mode 100644
> > >>>>  index 0000000..beafbf9
> > >>>>  --- /dev/null
> > >>>>  +++
> > >>>>
> > >>>
> >
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
> > >>>>  @@ -0,0 +1,32 @@
> > >>>>  +/*
> > >>>>  + * Licensed to the Apache Software Foundation (ASF) under one
> > >>>>  + * or more contributor license agreements.  See the NOTICE file
> > >>>>  + * distributed with this work for additional information
> > >>>>  + * regarding copyright ownership.  The ASF licenses this file
> > >>>>  + * to you under the Apache License, Version 2.0 (the
> > >>>>  + * "License"); you may not use this file except in compliance
> > >>>>  + * with the License.  You may obtain a copy of the License at
> > >>>>  + *
> > >>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
> > >>>>  + *
> > >>>>  + * Unless required by applicable law or agreed to in writing,
> > >>>>  + * software distributed under the License is distributed on an
> > >>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>>>  + * KIND, either express or implied.  See the License for the
> > >>>>  + * specific language governing permissions and limitations
> > >>>>  + * under the License.
> > >>>>  + */
> > >>>>  +package org.apache.tamaya.core.testdata;
> > >>>>  +
> > >>>>  +import org.apache.tamaya.core.PathBasedPropertySourceProvider;
> > >>>>  +import org.apache.tamaya.core.formats.PropertiesFormat;
> > >>>>  +
> > >>>>  +/**
> > >>>>  + * Test provider reading properties from
> > >>> classpath:cfg/final/**.properties.
> > >>>>  + */
> > >>>>  +public class TestPropertySourceProvider extends
> > >>>>  PathBasedPropertySourceProvider{
> > >>>>  +
> > >>>>  +    public TestPropertySourceProvider() {
> > >>>>  +        super("final-testdata-properties", new
> > >>> PropertiesFormat(200),
> > >>>>  "classpath:cfg/final/**/*.properties");
> > >>>>  +    }
> > >>>>  +}
> > >>>>
> > >>>>
> > >>>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
> > >>>>
> > ----------------------------------------------------------------------
> > >>>>  diff --git
> > >>>>
> > >>>
> >
> a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
> > >>>
> > >>>>
> > >>>
> >
> b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
> > >>>>  deleted file mode 100644
> > >>>>  index e6f7fad..0000000
> > >>>>  ---
> > >>>>
> > >>>
> >
> a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
> > >>>>  +++ /dev/null
> > >>>>  @@ -1,19 +0,0 @@
> > >>>>  -#
> > >>>>  -# Licensed to the Apache Software Foundation (ASF) under one
> > >>>>  -# or more contributor license agreements.  See the NOTICE file
> > >>>>  -# distributed with this work for additional information
> > >>>>  -# regarding copyright ownership.  The ASF licenses this file
> > >>>>  -# to you under the Apache License, Version 2.0 (the
> > >>>>  -# "License"); you may not use this file except in compliance
> > >>>>  -# with the License.  You may obtain a copy current the License at
> > >>>>  -#
> > >>>>  -#    http://www.apache.org/licenses/LICENSE-2.0
> > >>>>  -#
> > >>>>  -# Unless required by applicable law or agreed to in writing,
> > >>>>  -# software distributed under the License is distributed on an
> > >>>>  -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>>>  -# KIND, either express or implied.  See the License for the
> > >>>>  -# specific language governing permissions and limitations
> > >>>>  -# under the License.
> > >>>>  -#
> > >>>>  -org.apache.tamaya.core.testdata.TestPropertySource
> > >>>>  \ No newline at end of file
> > >>>>
> > >>>>
> > >>>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
> > >>>>
> > ----------------------------------------------------------------------
> > >>>>  diff --git
> > >>>>
> > >>>
> >
> a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
> > >>>
> > >>>>
> > >>>
> >
> b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
> > >>>>  new file mode 100644
> > >>>>  index 0000000..9db0ef4
> > >>>>  --- /dev/null
> > >>>>  +++
> > >>>>
> > >>>
> >
> b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
> > >>>>  @@ -0,0 +1,20 @@
> > >>>>  +#
> > >>>>  +# Licensed to the Apache Software Foundation (ASF) under one
> > >>>>  +# or more contributor license agreements.  See the NOTICE file
> > >>>>  +# distributed with this work for additional information
> > >>>>  +# regarding copyright ownership.  The ASF licenses this file
> > >>>>  +# to you under the Apache License, Version 2.0 (the
> > >>>>  +# "License"); you may not use this file except in compliance
> > >>>>  +# with the License.  You may obtain a copy current the License at
> > >>>>  +#
> > >>>>  +#    http://www.apache.org/licenses/LICENSE-2.0
> > >>>>  +#
> > >>>>  +# Unless required by applicable law or agreed to in writing,
> > >>>>  +# software distributed under the License is distributed on an
> > >>>>  +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>>>  +# KIND, either express or implied.  See the License for the
> > >>>>  +# specific language governing permissions and limitations
> > >>>>  +# under the License.
> > >>>>  +#
> > >>>>  +org.apache.tamaya.core.testdata.TestPropertyDefaultSourceProvider
> > >>>>  +org.apache.tamaya.core.testdata.TestPropertySourceProvider
> > >>>>  \ No newline at end of file
> > >>>>
> > >>>
> > >>
> > >
> > >
> >
>



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

Re: [2/4] incubator-tamaya git commit: TAMAYA-42, 43, 44: Readded non Spring related parts. Simplified resource API. Readded other tests.

Posted by Romain Manni-Bucau <rm...@gmail.com>.
I would be more brutal: JsonSource(URL), PropertiesSource(URL),
YamlSource(URL) etc...

URL is the unique Resource abstraction we need IMO for resources. Updates
will be detected by a source related event (for files WatchService, for
other polling for instance or even manual trigger etc....). So no need of
lastModified etc in the API.
Le 4 janv. 2015 10:33, "Mark Struberg" <st...@yahoo.de> a écrit :

> >Spring logic is more advanced - and broken IMO.
> Totally agree. This was always targeted to allow configuration from inside
> the Spring XML files. This is essentially scripting. But we don't have this.
> >This means all classloader usages would be excluded.
>
> No, it's perfectly fine to have _some_ PropertySources who read up values
> from the ClassPath. Those are default configs for the app. And this also
> allows some kind of flexible application approach like just adding a jar
> and overriding some of it's configuration values in your own project.
>
> Of course there are also PropertySources (JNDI, env and system by default
> but you could also add your own very easily) who don't rely on the
> ClassPath but 'inject' information from outside the application (ops,
> database, etc - whatever you like). And those PropertySources have a higher
> ordinal than the property files from your classpath.
>
>
> > If this is accepted you only need to be able to provide an URL
> > to an existing source to be able to read it so format is the source
> > if it has an URL constructor which makes thing really easier IMO.
>
>
> That could be fine. If I understood you correctly then you would add a
> 'BasePropertySource' (better name needed ofc). which is in the spi package
> of our api module? And it has a constructor with the URL it should read? Or
> did I get this wrong?
>
> LieGrue,
> strub
>
>
> On Sunday, 4 January 2015, 10:15, Romain Manni-Bucau <
> rmannibucau@gmail.com> wrote:
> >
> >Spring logic is more advanced - and broken IMO. It can read from a
> particular jar depending syntax and where it is read from.
> >It brings me to the first question we should have tackled: what is a
> config? For me it is all values which can be hardcoded and then cant be
> packaged inside the app - otherwise you break the predicate "i dont need to
> update my app for a config update". This means all classloader usages would
> be excluded. If this is accepted you only need to be able to provide an URL
> to an existing source to be able to read it so format is the source if it
> has an URL constructor which makes thing really easier IMO.
> >Wdyt?
> >
> >Le 4 janv. 2015 10:09, "Mark Struberg" <st...@yahoo.de> a écrit :
> >
> >I just became aware that maybe my VOTE was not clear enough.
> >>
> >>> 2.) Wouldn't it be easier to write the functionality ourselves
> >>> and be able to only implement the pieces we really need?
> >>> Currently all we need is ClassLoader.getResources() and be done.
> >>
> >>My aim was not to implement ALL the functionality originally taken from
> Spring but really only the things we need.
> >>And essentially the following:
> >>
> >>> Currently all we need is ClassLoader.getResources() and be done.
> >>
> >>
> >>Reading Properties from a resource is essentially a single line of code:
> >>
> >>
> >>java.util.Properties.load(ClassLoader.getResource(fileUrl).openStream());
> >>
> >>I don't yet get the benefit of the other code. Please explain.
> >>
> >>
> >>LieGrue,
> >>strub
> >>
> >>
> >>
> >>
> >>
> >>> On Sunday, 4 January 2015, 9:10, Mark Struberg <st...@yahoo.de>
> wrote:
> >>> > Anatole, WHY do we need all of this?
> >>>
> >>> It is NOWHERE used!
> >>>
> >>> Why do we add 21 classes which don't provide anything useful to the
> project?
> >>> There was even a VOTE that we should keep it simple and just do the
> things we
> >>> need.
> >>>
> >>> I really don't get it. Is our goal to create a lightweight but flexible
> >>> configuration system or is our goal to become big and fat?
> >>>
> >>>
> >>> Maybe it makes sense but if so then please explain it to us.
> >>>
> >>>
> >>> 1.) Why do we read in a specific format?
> >>>
> >>> All the system is handling String/String and only in the last step it
> *probably*
> >>> gets converted into a target Type. I fail to see the benefit. Please
> explain it
> >>> to us.
> >>>
> >>> 2.) Why do we need all the Resource implementations?
> >>>
> >>> Java provides Resource handling out of the box. Again: we don't need
> any
> >>> scripting. So why add some handling for dynamic scenarios which we do
> not have?
> >>> This is basically a copy of Spring.io. But we simply don't have
> anything
> >>> scripted in XML as Spring does. So why should we add it?
> >>>
> >>>
> >>> I'm really tired of seeing code all over the place which is not
> helpful for
> >>> the project. Please don't add things we don't really need.
> >>>
> >>>
> >>> LieGrue,
> >>> strub
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>>  On Sunday, 4 January 2015, 2:52, "anatole@apache.org"
> >>> <an...@apache.org> wrote:
> >>>>  >T AMAYA-42,43,44: Readded non Spring related parts. Simplified
> resource
> >>> API.
> >>>>  Readded other tests.
> >>>>
> >>>>
> >>>>  Project:
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo
> >>>>  Commit:
> >>>
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/cc237eb4
> >>>>  Tree:
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/cc237eb4
> >>>>  Diff:
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/cc237eb4
> >>>>
> >>>>  Branch: refs/heads/master
> >>>>  Commit: cc237eb41b7d0c660261f451f47bbf07b7770c46
> >>>>  Parents: 59a9e21
> >>>>  Author: anatole <an...@apache.org>
> >>>>  Authored: Sun Jan 4 02:17:56 2015 +0100
> >>>>  Committer: anatole <an...@apache.org>
> >>>>  Committed: Sun Jan 4 02:26:23 2015 +0100
> >>>>
> >>>>
> ----------------------------------------------------------------------
> >>>>  .../org/apache/tamaya/spi/PropertyFilter.java   |  10 +-
> >>>>  .../core/PathBasedPropertySourceProvider.java   |  93 ++++++++++
> >>>>  .../core/ResourcePropertySourceProvider.java    | 102 +++++++++++
> >>>>  .../core/formats/ConfigurationFormat.java       |  53 ++++++
> >>>>  .../tamaya/core/formats/PropertiesFormat.java   | 114 ++++++++++++
> >>>>  .../core/formats/PropertiesXmlFormat.java       | 115 ++++++++++++
> >>>>  .../core/internal/DefaultConfiguration.java     |  27 ++-
> >>>>  .../internal/resource/ClassPathResource.java    | 178
> +++++++++++++++++++
> >>>>  .../resource/DefaultResourceLoader.java         |  93 ++++++++++
> >>>>  .../core/internal/resource/FileResource.java    | 162
> +++++++++++++++++
> >>>>  .../internal/resource/InputStreamResource.java  | 117 ++++++++++++
> >>>>  .../core/resources/InputStreamSupplier.java     |  37 ++++
> >>>>  .../apache/tamaya/core/resources/Resource.java  | 115 ++++++++++++
> >>>>  .../tamaya/core/resources/ResourceLoader.java   |  91 ++++++++++
> >>>>  .../apache/tamaya/core/ConfigurationTest.java   |   6 +
> >>>>  .../EnvironmentPropertySourceTest.java          |  70 --------
> >>>>  .../TestPropertyDefaultSourceProvider.java      |  32 ++++
> >>>>  .../core/testdata/TestPropertySource.java       |  55 ------
> >>>>  .../testdata/TestPropertySourceProvider.java    |  32 ++++
> >>>>  .../org.apache.tamaya.spi.PropertySource        |  19 --
> >>>>  ...org.apache.tamaya.spi.PropertySourceProvider |  20 +++
> >>>>  21 files changed, 1388 insertions(+), 153 deletions(-)
> >>>>
> ----------------------------------------------------------------------
> >>>>
> >>>>
> >>>>
> >>>
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> >>>>
> ----------------------------------------------------------------------
> >>>>  diff --git
> a/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> >>>>  b/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> >>>>  index 7479008..c8626fc 100644
> >>>>  --- a/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> >>>>  +++ b/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> >>>>  @@ -19,7 +19,7 @@
> >>>>  package org.apache.tamaya.spi;
> >>>>
> >>>>
> >>>>  -import java.util.Map;
> >>>>  +import java.util.function.Function;
> >>>>
> >>>>  /**
> >>>>    * <p>Interface for filtering the current map of properties during
> >>> the
> >>>>  evaluation of the chain of PropertySources.
> >>>>  @@ -27,7 +27,7 @@ import java.util.Map;
> >>>>    * hereby is defined by the corresponding {@code @Priority}
> >>>>  annotation.</p>
> >>>>    * <p>Filters </p>
> >>>>    */
> >>>>  -public interface PropertyFilter<T>{
> >>>>  +public interface PropertyFilter{
> >>>>
> >>>>       /**
> >>>>        * <p>Maps the current {@code valueToBeFiltered} value to a
> >>> new
> >>>>  value. The resulting value will be used as the result
> >>>>  @@ -44,10 +44,10 @@ public interface PropertyFilter<T>{
> >>>>        *
> >>>>        * @param key the key accessed, not null.
> >>>>        * @param valueToBeFiltered the value to be filtered, not null.
> >>>>  -     * @param currentMap the current input property map, not null.
> Can be
> >>> used
> >>>>  for resolution of the filtered value
> >>>>  -     *                   or as datasource for additional
> meta-information,
> >>> such
> >>>>  as categories, sensitivity etc.
> >>>>  +     * @param propertyValueProvider accessor for reading additional
> (eg
> >>>>  metadata) properties to perform correct
> >>>>  +     *                              filtering, never null.
> >>>>        * @return the filtered map, never null.
> >>>>        */
> >>>>  -    String filterProperty(String key, String valueToBeFiltered,
> >>>>  Map<String,String> currentMap);
> >>>>  +    String filterProperty(String key, String valueToBeFiltered,
> >>>>  Function<String,String> propertyValueProvider);
> >>>>
> >>>>  }
> >>>>
> >>>>
> >>>
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
> >>>>
> ----------------------------------------------------------------------
> >>>>  diff --git
> >>>>
> >>>
> a/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
> >>>
> >>>>
> >>>
> b/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
> >>>>  new file mode 100644
> >>>>  index 0000000..31dbf4b
> >>>>  --- /dev/null
> >>>>  +++
> >>>>
> >>>
> b/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
> >>>>  @@ -0,0 +1,93 @@
> >>>>  +/*
> >>>>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>>>  + * or more contributor license agreements.  See the NOTICE file
> >>>>  + * distributed with this work for additional information
> >>>>  + * regarding copyright ownership.  The ASF licenses this file
> >>>>  + * to you under the Apache License, Version 2.0 (the
> >>>>  + * "License"); you may not use this file except in compliance
> >>>>  + * with the License.  You may obtain a copy of the License at
> >>>>  + *
> >>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>>>  + *
> >>>>  + * Unless required by applicable law or agreed to in writing,
> >>>>  + * software distributed under the License is distributed on an
> >>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>>>  + * KIND, either express or implied.  See the License for the
> >>>>  + * specific language governing permissions and limitations
> >>>>  + * under the License.
> >>>>  + */
> >>>>  +package org.apache.tamaya.core;
> >>>>  +
> >>>>  +import org.apache.tamaya.core.formats.ConfigurationFormat;
> >>>>  +import org.apache.tamaya.core.resources.Resource;
> >>>>  +import org.apache.tamaya.core.resources.ResourceLoader;
> >>>>  +import org.apache.tamaya.spi.PropertySource;
> >>>>  +import org.apache.tamaya.spi.PropertySourceProvider;
> >>>>  +import org.apache.tamaya.spi.ServiceContext;
> >>>>  +
> >>>>  +import java.util.ArrayList;
> >>>>  +import java.util.Arrays;
> >>>>  +import java.util.Collection;
> >>>>  +import java.util.List;
> >>>>  +import java.util.Objects;
> >>>>  +import java.util.logging.Level;
> >>>>  +import java.util.logging.Logger;
> >>>>  +
> >>>>  +/**
> >>>>  + * Implementation of a {@link PropertySourceProvider} that reads
> >>>>  configuration from some given resource paths
> >>>>  + * and using the given formats. The resource path are resolved
> using the
> >>>>  current
> >>>>  + * {@link org.apache.tamaya.core.resources.ResourceLoader} active.
> >>>>  + */
> >>>>  +public class PathBasedPropertySourceProvider implements
> >>> PropertySourceProvider
> >>>>  {
> >>>>  +    /** The logger used. */
> >>>>  +    private static final Logger LOG =
> >>>>  Logger.getLogger(PathBasedPropertySourceProvider.class.getName());
> >>>>  +    /** The property source base name, will be used for creating a
> useful
> >>> name
> >>>>  of the
> >>>>  +     * {@link org.apache.tamaya.spi.PropertySource} created. */
> >>>>  +    private String sourceName;
> >>>>  +    /** The config formats supported for the given location/resource
> >>> paths. */
> >>>>  +    private List<ConfigurationFormat> configFormats = new
> >>>>  ArrayList<>();
> >>>>  +    /** The paths to be evaluated. */
> >>>>  +    private List<String> paths = new ArrayList<>();
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Creates a new instance.
> >>>>  +     * @param sourceName the base name of the configuration, used
> for
> >>> creating
> >>>>  PropertySource child names.
> >>>>  +     * @param formats the formats to be used, not null, not empty.
> >>>>  +     * @param paths the paths to be resolved, not null, not empty.
> >>>>  +     */
> >>>>  +    public PathBasedPropertySourceProvider(String sourceName,
> >>>>  List<ConfigurationFormat> formats, String... paths) {
> >>>>  +        this.sourceName = Objects.requireNonNull(sourceName);
> >>>>  +        this.configFormats.addAll(Objects.requireNonNull(formats));
> >>>>  +
> this.paths.addAll(Arrays.asList(Objects.requireNonNull(paths)));
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Creates a new instance.
> >>>>  +     * @param sourceName the base name of the configuration, used
> for
> >>> creating
> >>>>  PropertySource child names.
> >>>>  +     * @param format the format to be used.
> >>>>  +     * @param paths the paths to be resolved, not null, not empty.
> >>>>  +     */
> >>>>  +    public PathBasedPropertySourceProvider(String sourceName,
> >>>>  ConfigurationFormat format, String... paths) {
> >>>>  +        this.sourceName = Objects.requireNonNull(sourceName);
> >>>>  +        this.configFormats.add(Objects.requireNonNull(format));
> >>>>  +
> this.paths.addAll(Arrays.asList(Objects.requireNonNull(paths)));
> >>>>  +    }
> >>>>  +
> >>>>  +    @Override
> >>>>  +    public Collection<PropertySource> getPropertySources() {
> >>>>  +        List<PropertySource> propertySources = new
> >>> ArrayList<>();
> >>>>  +        paths.forEach((path) -> {
> >>>>  +            for (Resource res :
> >>>>
> >>>
> ServiceContext.getInstance().getService(ResourceLoader.class).get().getResources(path))
> >>>
> >>>>  {
> >>>>  +                try {
> >>>>  +                    for (ConfigurationFormat format : configFormats)
> >>> {
> >>>>  +
> >>>>  propertySources.addAll(format.readConfiguration(sourceName, res));
> >>>>  +                    }
> >>>>  +                } catch (Exception e) {
> >>>>  +                    LOG.log(Level.WARNING, "Failed to add resource
> >>> based
> >>>>  config: " + res.getName(), e);
> >>>>  +                }
> >>>>  +            }
> >>>>  +        });
> >>>>  +        return propertySources;
> >>>>  +    }
> >>>>  +
> >>>>  +}
> >>>>
> >>>>
> >>>
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
> >>>>
> ----------------------------------------------------------------------
> >>>>  diff --git
> >>>>
> >>>
> a/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
> >>>>
> >>>
> b/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
> >>>>  new file mode 100644
> >>>>  index 0000000..de6b578
> >>>>  --- /dev/null
> >>>>  +++
> >>>>
> >>>
> b/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
> >>>>  @@ -0,0 +1,102 @@
> >>>>  +/*
> >>>>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>>>  + * or more contributor license agreements.  See the NOTICE file
> >>>>  + * distributed with this work for additional information
> >>>>  + * regarding copyright ownership.  The ASF licenses this file
> >>>>  + * to you under the Apache License, Version 2.0 (the
> >>>>  + * "License"); you may not use this file except in compliance
> >>>>  + * with the License.  You may obtain a copy of the License at
> >>>>  + *
> >>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>>>  + *
> >>>>  + * Unless required by applicable law or agreed to in writing,
> >>>>  + * software distributed under the License is distributed on an
> >>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>>>  + * KIND, either express or implied.  See the License for the
> >>>>  + * specific language governing permissions and limitations
> >>>>  + * under the License.
> >>>>  + */
> >>>>  +package org.apache.tamaya.core;
> >>>>  +
> >>>>  +import org.apache.tamaya.core.formats.ConfigurationFormat;
> >>>>  +import org.apache.tamaya.core.resources.Resource;
> >>>>  +import org.apache.tamaya.spi.PropertySource;
> >>>>  +import org.apache.tamaya.spi.PropertySourceProvider;
> >>>>  +
> >>>>  +import java.util.ArrayList;
> >>>>  +import java.util.Arrays;
> >>>>  +import java.util.Collection;
> >>>>  +import java.util.List;
> >>>>  +import java.util.Objects;
> >>>>  +import java.util.logging.Logger;
> >>>>  +
> >>>>  +/**
> >>>>  + * Implementation of a {@link
> >>>>  org.apache.tamaya.spi.PropertySourceProvider} that is based on a
> single
> >>> resource
> >>>>  + * and a number of formats.
> >>>>  + */
> >>>>  +public class ResourcePropertySourceProvider implements
> >>> PropertySourceProvider
> >>>>  {
> >>>>  +    /** The logger used. */
> >>>>  +    private static final Logger LOG =
> >>>>  Logger.getLogger(ResourcePropertySourceProvider.class.getName());
> >>>>  +    /** The supported formats. */
> >>>>  +    private List<ConfigurationFormat> formats = new
> >>> ArrayList<>();
> >>>>  +    /** The resource. */
> >>>>  +    private Resource resource;
> >>>>  +    /** The source name used for creating the PropertySource names.
> */
> >>>>  +    private String sourceName;
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Creates a new instance.
> >>>>  +     * @param resource the {@link
> >>>>  org.apache.tamaya.core.resources.Resource}, not null.
> >>>>  +     * @param formats the supported formats, not empty.
> >>>>  +     */
> >>>>  +    public ResourcePropertySourceProvider(String sourceName,
> Resource
> >>> resource,
> >>>>  ConfigurationFormat... formats) {
> >>>>  +        this(sourceName, resource, Arrays.asList(formats));
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Creates a new instance.
> >>>>  +     * @param resource the {@link
> >>>>  org.apache.tamaya.core.resources.Resource}, not null.
> >>>>  +     * @param formats the supported formats, not empty.
> >>>>  +     */
> >>>>  +    public ResourcePropertySourceProvider(String sourceName,
> Resource
> >>> resource,
> >>>>  List<ConfigurationFormat> formats) {
> >>>>  +        this.resource = Objects.requireNonNull(resource);
> >>>>  +        this.sourceName = Objects.requireNonNull(sourceName);
> >>>>  +        if(formats.size()==0){
> >>>>  +            throw new IllegalArgumentException("Format
> >>> required.");
> >>>>  +        }
> >>>>  +        this.formats.addAll(formats);
> >>>>  +    }
> >>>>  +
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Get the underlying resource.
> >>>>  +     *
> >>>>  +     * @return the underlying resource, never null.
> >>>>  +     */
> >>>>  +    public Resource getResource() {
> >>>>  +        return this.resource;
> >>>>  +    }
> >>>>  +
> >>>>  +
> >>>>  +    @Override
> >>>>  +    public String toString() {
> >>>>  +        return "ResourcePropertySourceProvider{" +
> >>>>  +                "resource=" + resource +
> >>>>  +                ", formats=+" + formats +
> >>>>  +                '}';
> >>>>  +    }
> >>>>  +
> >>>>  +    @Override
> >>>>  +    public Collection<PropertySource> getPropertySources() {
> >>>>  +        List<PropertySource> propertySources = new
> >>> ArrayList<>();
> >>>>  +        for (ConfigurationFormat format : formats) {
> >>>>  +            try {
> >>>>  +
> >>> propertySources.addAll(format.readConfiguration(sourceName,
> >>>>  resource));
> >>>>  +            } catch (Exception e) {
> >>>>  +                LOG.info(() -> "Format was not matching: " +
> >>>>  format + " for resource: " + resource.getName());
> >>>>  +            }
> >>>>  +        }
> >>>>  +        return propertySources;
> >>>>  +    }
> >>>>  +
> >>>>  +}
> >>>>
> >>>>
> >>>
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
> >>>>
> ----------------------------------------------------------------------
> >>>>  diff --git
> >>>>
> >>>
> a/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
> >>>>
> >>>
> b/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
> >>>>  new file mode 100644
> >>>>  index 0000000..5d289bb
> >>>>  --- /dev/null
> >>>>  +++
> >>>
> b/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
> >>>>  @@ -0,0 +1,53 @@
> >>>>  +/*
> >>>>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>>>  + * or more contributor license agreements.  See the NOTICE file
> >>>>  + * distributed with this work for additional information
> >>>>  + * regarding copyright ownership.  The ASF licenses this file
> >>>>  + * to you under the Apache License, Version 2.0 (the
> >>>>  + * "License"); you may not use this file except in compliance
> >>>>  + * with the License.  You may obtain a copy of the License at
> >>>>  + *
> >>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>>>  + *
> >>>>  + * Unless required by applicable law or agreed to in writing,
> >>>>  + * software distributed under the License is distributed on an
> >>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>>>  + * KIND, either express or implied.  See the License for the
> >>>>  + * specific language governing permissions and limitations
> >>>>  + * under the License.
> >>>>  + */
> >>>>  +package org.apache.tamaya.core.formats;
> >>>>  +
> >>>>  +import org.apache.tamaya.core.resources.Resource;
> >>>>  +import org.apache.tamaya.spi.PropertySource;
> >>>>  +
> >>>>  +import java.io.IOException;
> >>>>  +import java.util.Collection;
> >>>>  +
> >>>>  +/**
> >>>>  + * Implementations current this class encapsulate the mechanism how
> to
> >>> read a
> >>>>  + * resource including interpreting the format correctly (e.g. xml
> vs.
> >>>>  + * properties). In most cases file only contains entries of the same
> >>> priority,
> >>>>  which would then
> >>>>  + * result in only one {@link PropertySource}. Complex file formats,
> >>>>  hoiwever, may contain entries
> >>>>  + * of different priorities. In this cases, each ordinal type found
> must be
> >>>
> >>>>  returned as a separate
> >>>>  + * {@link PropertySource} instance.
> >>>>  + */
> >>>>  +@FunctionalInterface
> >>>>  +public interface ConfigurationFormat {
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Reads a list {@link org.apache.tamaya.spi.PropertySource}
> >>> instances
> >>>>  from a resource, using this format.
> >>>>  +     * If the configuration format only contains entries of one
> ordinal
> >>> type,
> >>>>  normally only one single
> >>>>  +     * instance of PropertySource is returned. Nevertheless custom
> formats
> >>> may
> >>>>  contain different sections or parts,
> >>>>  +     * where each part maps to a different target rdinal (eg
> defaults,
> >>> domain
> >>>>  config and app config). In the
> >>>>  +     * ladder case multiple PropertySources can be returned, each
> one with
> >>> its
> >>>>  own ordinal and the corresponding
> >>>>  +     * entries.
> >>>>  +     *
> >>>>  +     * @param sourceName name to be used for constructing a useful
> name
> >>> for the
> >>>>  created
> >>>>  +     *                   {@link
> org.apache.tamaya.spi.PropertySource}
> >>>
> >>>>  instances.
> >>>>  +     * @param resource   the configuration resource, not null
> >>>>  +     * @return the corresponding {@link
> >>>>  org.apache.tamaya.spi.PropertySource} instances, never {@code null}.
> >>>>  +     */
> >>>>  +    Collection<PropertySource> readConfiguration(String sourceName,
> >>>>  Resource resource) throws IOException;
> >>>>  +
> >>>>  +}
> >>>>
> >>>>
> >>>
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
> >>>>
> ----------------------------------------------------------------------
> >>>>  diff --git
> >>>>
> a/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
> >>>>
> b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
> >>>>  new file mode 100644
> >>>>  index 0000000..3584f8e
> >>>>  --- /dev/null
> >>>>  +++
> >>>
> b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
> >>>>  @@ -0,0 +1,114 @@
> >>>>  +/*
> >>>>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>>>  + * or more contributor license agreements.  See the NOTICE file
> >>>>  + * distributed with this work for additional information
> >>>>  + * regarding copyright ownership.  The ASF licenses this file
> >>>>  + * to you under the Apache License, Version 2.0 (the
> >>>>  + * "License"); you may not use this file except in compliance
> >>>>  + * with the License.  You may obtain a copy of the License at
> >>>>  + *
> >>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>>>  + *
> >>>>  + * Unless required by applicable law or agreed to in writing,
> >>>>  + * software distributed under the License is distributed on an
> >>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>>>  + * KIND, either express or implied.  See the License for the
> >>>>  + * specific language governing permissions and limitations
> >>>>  + * under the License.
> >>>>  + */
> >>>>  +package org.apache.tamaya.core.formats;
> >>>>  +
> >>>>  +import org.apache.tamaya.core.resources.Resource;
> >>>>  +import org.apache.tamaya.spi.PropertySource;
> >>>>  +
> >>>>  +import java.io.InputStream;
> >>>>  +import java.util.ArrayList;
> >>>>  +import java.util.Collection;
> >>>>  +import java.util.Collections;
> >>>>  +import java.util.List;
> >>>>  +import java.util.Map;
> >>>>  +import java.util.Optional;
> >>>>  +import java.util.Properties;
> >>>>  +import java.util.logging.Level;
> >>>>  +import java.util.logging.Logger;
> >>>>  +
> >>>>  +/**
> >>>>  + * Implementation of a {@link
> >>>>  org.apache.tamaya.core.formats.ConfigurationFormat} for -properties
> files.
> >>>>  + *
> >>>>  + * @see java.util.Properties#load(java.io.InputStream)
> >>>>  + */
> >>>>  +public class PropertiesFormat implements ConfigurationFormat {
> >>>>  +    /**
> >>>>  +     * The logger.
> >>>>  +     */
> >>>>  +    private final static Logger LOG =
> >>>>  Logger.getLogger(PropertiesFormat.class.getName());
> >>>>  +
> >>>>  +    /**
> >>>>  +     * The target ordinal.
> >>>>  +     */
> >>>>  +    private int ordinal;
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Creates a new format instance, hereby producing entries with
> the
> >>> given
> >>>>  ordinal, if not overridden by the
> >>>>  +     * configuration itself.
> >>>>  +     * TODO document and implement override feature
> >>>>  +     * @param ordinal the target ordinal.
> >>>>  +     */
> >>>>  +    public PropertiesFormat(int ordinal) {
> >>>>  +        this.ordinal = ordinal;
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Get the target ordinal, produced by this format.
> >>>>  +     *
> >>>>  +     * @return the target ordinal
> >>>>  +     */
> >>>>  +    public int getOrdinal() {
> >>>>  +        return ordinal;
> >>>>  +    }
> >>>>  +
> >>>>  +    @SuppressWarnings("unchecked")
> >>>>  +    @Override
> >>>>  +    public Collection<PropertySource> readConfiguration(String
> >>> baseName,
> >>>>  Resource resource) {
> >>>>  +        final String sourceName =
> >>>>  (baseName==null?"Properties:":baseName) + resource.getName();
> >>>>  +        if (resource.exists()) {
> >>>>  +            List<PropertySource> propertySources = new
> >>>>  ArrayList<>();
> >>>>  +            try (InputStream is = resource.getInputStream()) {
> >>>>  +                final Properties p = new Properties();
> >>>>  +                p.load(is);
> >>>>  +                propertySources.add(new PropertySource() {
> >>>>  +                    @Override
> >>>>  +                    public int getOrdinal() {
> >>>>  +                        return ordinal;
> >>>>  +                    }
> >>>>  +
> >>>>  +                    @Override
> >>>>  +                    public String getName() {
> >>>>  +                        return sourceName;
> >>>>  +                    }
> >>>>  +
> >>>>  +                    @Override
> >>>>  +                    public Optional<String> get(String key) {
> >>>>  +                        return
> Optional.ofNullable(p.getProperty(key));
> >>>>  +                    }
> >>>>  +
> >>>>  +                    @Override
> >>>>  +                    public Map<String, String> getProperties()
> >>> {
> >>>>  +                        return Map.class.cast(p);
> >>>>  +                    }
> >>>>  +                });
> >>>>  +                return propertySources;
> >>>>  +            } catch (Exception e) {
> >>>>  +                LOG.log(Level.FINEST, e, () -> "Failed to read
> >>> config
> >>>>  from resource: " + resource);
> >>>>  +            }
> >>>>  +        }
> >>>>  +        return Collections.emptyList();
> >>>>  +    }
> >>>>  +
> >>>>  +    @Override
> >>>>  +    public String toString() {
> >>>>  +        return "PropertiesFormat{" +
> >>>>  +                "ordinal=" + ordinal +
> >>>>  +                '}';
> >>>>  +    }
> >>>>  +}
> >>>>
> >>>>
> >>>
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
> >>>>
> ----------------------------------------------------------------------
> >>>>  diff --git
> >>>>
> >>>
> a/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
> >>>>
> >>>
> b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
> >>>>  new file mode 100644
> >>>>  index 0000000..3f77810
> >>>>  --- /dev/null
> >>>>  +++
> >>>
> b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
> >>>>  @@ -0,0 +1,115 @@
> >>>>  +/*
> >>>>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>>>  + * or more contributor license agreements.  See the NOTICE file
> >>>>  + * distributed with this work for additional information
> >>>>  + * regarding copyright ownership.  The ASF licenses this file
> >>>>  + * to you under the Apache License, Version 2.0 (the
> >>>>  + * "License"); you may not use this file except in compliance
> >>>>  + * with the License.  You may obtain a copy of the License at
> >>>>  + *
> >>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>>>  + *
> >>>>  + * Unless required by applicable law or agreed to in writing,
> >>>>  + * software distributed under the License is distributed on an
> >>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>>>  + * KIND, either express or implied.  See the License for the
> >>>>  + * specific language governing permissions and limitations
> >>>>  + * under the License.
> >>>>  + */
> >>>>  +package org.apache.tamaya.core.formats;
> >>>>  +
> >>>>  +import org.apache.tamaya.core.resources.Resource;
> >>>>  +import org.apache.tamaya.spi.PropertySource;
> >>>>  +
> >>>>  +import java.io.InputStream;
> >>>>  +import java.util.ArrayList;
> >>>>  +import java.util.Collection;
> >>>>  +import java.util.Collections;
> >>>>  +import java.util.List;
> >>>>  +import java.util.Map;
> >>>>  +import java.util.Optional;
> >>>>  +import java.util.Properties;
> >>>>  +import java.util.logging.Level;
> >>>>  +import java.util.logging.Logger;
> >>>>  +
> >>>>  +/**
> >>>>  + * Implementation of a {@link
> >>>>  org.apache.tamaya.core.formats.ConfigurationFormat} for xml property
> >>>>  + * files.
> >>>>  + *
> >>>>  + * @see java.util.Properties#loadFromXML(java.io.InputStream)
> >>>>  + */
> >>>>  +public class PropertiesXmlFormat implements ConfigurationFormat {
> >>>>  +    /**
> >>>>  +     * The logger.
> >>>>  +     */
> >>>>  +    private final static Logger LOG =
> >>>>  Logger.getLogger(PropertiesXmlFormat.class.getName());
> >>>>  +
> >>>>  +    /**
> >>>>  +     * The target ordinal.
> >>>>  +     */
> >>>>  +    private int ordinal;
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Creates a new format instance, producing entries for the
> given
> >>> ordinal,
> >>>>  if not overridden by a
> >>>>  +     * config entry itself.
> >>>>  +     * TODO document and implement override feature
> >>>>  +     * @param ordinal the target ordinal.
> >>>>  +     */
> >>>>  +    public PropertiesXmlFormat(int ordinal) {
> >>>>  +        this.ordinal = ordinal;
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Get the target ordinal, produced by this format.
> >>>>  +     *
> >>>>  +     * @return the target ordinal
> >>>>  +     */
> >>>>  +    public int getOrdinal() {
> >>>>  +        return ordinal;
> >>>>  +    }
> >>>>  +
> >>>>  +    @SuppressWarnings("unchecked")
> >>>>  +    @Override
> >>>>  +    public Collection<PropertySource> readConfiguration(String
> >>> baseName,
> >>>>  Resource resource) {
> >>>>  +        if (resource.exists()) {
> >>>>  +            final String sourceName =
> >>>>  (baseName==null?"Properties:":baseName) + resource.getName();
> >>>>  +            List<PropertySource> propertySources = new
> >>>>  ArrayList<>();
> >>>>  +            try (InputStream is = resource.getInputStream()) {
> >>>>  +                final Properties p = new Properties();
> >>>>  +                p.loadFromXML(is);
> >>>>  +                propertySources.add(new PropertySource() {
> >>>>  +                    @Override
> >>>>  +                    public int getOrdinal() {
> >>>>  +                        return ordinal;
> >>>>  +                    }
> >>>>  +
> >>>>  +                    @Override
> >>>>  +                    public String getName() {
> >>>>  +                        return sourceName;
> >>>>  +                    }
> >>>>  +
> >>>>  +                    @Override
> >>>>  +                    public Optional<String> get(String key) {
> >>>>  +                        return
> Optional.ofNullable(p.getProperty(key));
> >>>>  +                    }
> >>>>  +
> >>>>  +                    @Override
> >>>>  +                    public Map<String, String> getProperties()
> >>> {
> >>>>  +                        return Map.class.cast(p);
> >>>>  +                    }
> >>>>  +                });
> >>>>  +                return propertySources;
> >>>>  +            } catch (Exception e) {
> >>>>  +                LOG.log(Level.FINEST, e, () -> "Failed to read
> >>> config
> >>>>  from resource: " + resource);
> >>>>  +            }
> >>>>  +        }
> >>>>  +        return Collections.emptyList();
> >>>>  +    }
> >>>>  +
> >>>>  +    @Override
> >>>>  +    public String toString() {
> >>>>  +        return "PropertiesXmlFormat{" +
> >>>>  +                "ordinal=" + ordinal +
> >>>>  +                '}';
> >>>>  +    }
> >>>>  +}
> >>>>
> >>>>
> >>>
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> >>>>
> ----------------------------------------------------------------------
> >>>>  diff --git
> >>>>
> >>>
> a/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> >>>>
> >>>
> b/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> >>>>  index 0a39b7d..3769e27 100644
> >>>>  ---
> >>>>
> >>>
> a/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> >>>>  +++
> >>>>
> >>>
> b/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> >>>>  @@ -22,6 +22,7 @@ import org.apache.tamaya.ConfigException;
> >>>>  import org.apache.tamaya.Configuration;
> >>>>  import org.apache.tamaya.spi.ConfigurationContext;
> >>>>  import org.apache.tamaya.spi.PropertyConverter;
> >>>>  +import org.apache.tamaya.spi.PropertyFilter;
> >>>>  import org.apache.tamaya.spi.PropertySource;
> >>>>  import org.apache.tamaya.spi.ServiceContext;
> >>>>
> >>>>  @@ -33,6 +34,7 @@ import java.util.Map;
> >>>>  import java.util.Optional;
> >>>>  import java.util.logging.Level;
> >>>>  import java.util.logging.Logger;
> >>>>  +import java.util.stream.Collectors;
> >>>>
> >>>>  /**
> >>>>    * Implementation of the Configuration API. This class uses the
> current
> >>>>  {@link ConfigurationContext} to evaluate the
> >>>>  @@ -56,13 +58,21 @@ public class DefaultConfiguration implements
> >>> Configuration
> >>>>  {
> >>>>       @Override
> >>>>       public Optional<String> get(String key) {
> >>>>           List<PropertySource> propertySources =
> >>>>
> >>>
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertySources();
> >>>>  +        String unfilteredValue = null;
> >>>>           for (PropertySource propertySource : propertySources) {
> >>>>               Optional<String> value = propertySource.get(key);
> >>>>               if (value.isPresent()) {
> >>>>  -                return value;
> >>>>  +                unfilteredValue = value.get();
> >>>>  +                break;
> >>>>               }
> >>>>           }
> >>>>  -        return Optional.empty();
> >>>>  +        // Apply filters to values, prevent values filtered to null!
> >>>>  +        for(PropertyFilter filter:
> >>>>  +
> >>>>
> >>>
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyFilters()){
> >>>>  +            unfilteredValue = filter.filterProperty(key,
> unfilteredValue,
> >>>>  +                    (String k) ->
> >>> key.equals(k)?null:get(k).orElse(null));
> >>>>  +        }
> >>>>  +        return Optional.ofNullable(unfilteredValue);
> >>>>       }
> >>>>
> >>>>       @Override
> >>>>  @@ -83,7 +93,15 @@ public class DefaultConfiguration implements
> >>> Configuration
> >>>>  {
> >>>>                   LOG.log(Level.SEVERE, "Error adding properties from
> >>>>  PropertySource: " + propertySource +", ignoring
> >>> PropertySource.",
> >>>>  e);
> >>>>               }
> >>>>           }
> >>>>  -        return result;
> >>>>  +        // Apply filters to values, prevent values filtered to null!
> >>>>  +        for(PropertyFilter filter:
> >>>>  +
> >>>>
> >>>
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyFilters()){
> >>>>  +            result.replaceAll((k,v) -> filter.filterProperty(k, v,
> >>>>  +                    (String k2) ->
> >>> k2.equals(k)?null:get(k2).orElse(null)));
> >>>>  +        }
> >>>>  +        // Remove null values
> >>>>  +        return result.entrySet().parallelStream().filter((e) ->
> >>>>  e.getValue()!=null).collect(
> >>>>  +                Collectors.toMap((e) -> e.getKey(), (e) ->
> >>>>  e.getValue()));
> >>>>       }
> >>>>
> >>>>       /**
> >>>>  @@ -101,7 +119,8 @@ public class DefaultConfiguration implements
> >>> Configuration
> >>>>  {
> >>>>       public <T> Optional<T> get(String key, Class<T>
> >>> type)
> >>>>  {
> >>>>           Optional<String> value = get(key);
> >>>>           if (value.isPresent()) {
> >>>>  -            List<PropertyConverter<T>> converters =
> >>>>
> >>>
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyConverters(type);
> >>>>  +            List<PropertyConverter<T>> converters =
> >>>>  ServiceContext.getInstance().getService(ConfigurationContext.class)
> >>>>  +                    .get().getPropertyConverters(type);
> >>>>               for (PropertyConverter<T> converter : converters) {
> >>>>                   try {
> >>>>                       T t = converter.convert(value.get());
> >>>>
> >>>>
> >>>
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
> >>>>
> ----------------------------------------------------------------------
> >>>>  diff --git
> >>>>
> >>>
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
> >>>
> >>>>
> >>>
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
> >>>>  new file mode 100644
> >>>>  index 0000000..21806cd
> >>>>  --- /dev/null
> >>>>  +++
> >>>>
> >>>
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
> >>>>  @@ -0,0 +1,178 @@
> >>>>  +/*
> >>>>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>>>  + * or more contributor license agreements.  See the NOTICE file
> >>>>  + * distributed with this work for additional information
> >>>>  + * regarding copyright ownership.  The ASF licenses this file
> >>>>  + * to you under the Apache License, Version 2.0 (the
> >>>>  + * "License"); you may not use this file except in compliance
> >>>>  + * with the License.  You may obtain a copy of the License at
> >>>>  + *
> >>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>>>  + *
> >>>>  + * Unless required by applicable law or agreed to in writing,
> >>>>  + * software distributed under the License is distributed on an
> >>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>>>  + * KIND, either express or implied.  See the License for the
> >>>>  + * specific language governing permissions and limitations
> >>>>  + * under the License.
> >>>>  + */
> >>>>  +package org.apache.tamaya.core.internal.resource;
> >>>>  +
> >>>>  +import org.apache.tamaya.core.resources.Resource;
> >>>>  +
> >>>>  +import java.io.IOException;
> >>>>  +import java.io.InputStream;
> >>>>  +import java.net.URI;
> >>>>  +import java.net.URISyntaxException;
> >>>>  +import java.net.URL;
> >>>>  +import java.util.Objects;
> >>>>  +
> >>>>  +/**
> >>>>  + * Implementation of {@link Resource} to be loaded from the
> >>> classpath.
> >>>>  + */
> >>>>  +public class ClassPathResource implements Resource {
> >>>>  +
> >>>>  +    private final String path;
> >>>>  +
> >>>>  +    private ClassLoader classLoader;
> >>>>  +
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Create a new resource using the current context class loader.
> >>>>  +     *
> >>>>  +     * @param path the resource path, not null
> >>>>  +     * @see java.lang.ClassLoader#getResourceAsStream(String)
> >>>>  +     */
> >>>>  +    public ClassPathResource(String path) {
> >>>>  +        this(path, (ClassLoader) null);
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Create a new resource using the given class loader.
> >>>>  +     *
> >>>>  +     * @param path        the resource path, not null
> >>>>  +     * @param classLoader the class loader to load the resource
> with,
> >>>>  +     *                    or {@code null} for the current context
> >>> class
> >>>>  loader
> >>>>  +     * @see ClassLoader#getResourceAsStream(String)
> >>>>  +     */
> >>>>  +    public ClassPathResource(String path, ClassLoader classLoader) {
> >>>>  +        Objects.requireNonNull(path, "Path null");
> >>>>  +        if (path.startsWith("/")) {
> >>>>  +            path = path.substring(1);
> >>>>  +        }
> >>>>  +        this.path = path.trim();
> >>>>  +        if(classLoader==null){
> >>>>  +            classLoader =
> Thread.currentThread().getContextClassLoader();
> >>>>  +        }
> >>>>  +        if(classLoader==null){
> >>>>  +            classLoader = getClass().getClassLoader();
> >>>>  +        }
> >>>>  +        this.classLoader = classLoader;
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * @return the path for this resource.
> >>>>  +     */
> >>>>  +    public final String getPath() {
> >>>>  +        return this.path;
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * @return the ClassLoader that this resource will be accessed
> from.
> >>>>  +     */
> >>>>  +    public final ClassLoader getClassLoader() {
> >>>>  +        return this.classLoader;
> >>>>  +    }
> >>>>  +
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Checks if the given resource is resolvable from the
> configured
> >>>>  classloader.
> >>>>  +     *
> >>>>  +     * @see java.lang.ClassLoader#getResource(String)
> >>>>  +     */
> >>>>  +    @Override
> >>>>  +    public boolean exists() {
> >>>>  +        return (resolveURL() != null);
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Resolves a URL for the underlying class path resource.
> >>>>  +     *
> >>>>  +     * @return the resolved URL, or {@code null}
> >>>>  +     */
> >>>>  +    protected URL resolveURL() {
> >>>>  +        return this.classLoader.getResource(this.path);
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * This implementation opens an InputStream for the given class
> path
> >>>>  resource.
> >>>>  +     *
> >>>>  +     * @see java.lang.ClassLoader#getResourceAsStream(String)
> >>>>  +     * @see java.lang.Class#getResourceAsStream(String)
> >>>>  +     */
> >>>>  +    @Override
> >>>>  +    public InputStream getInputStream() throws IOException {
> >>>>  +        InputStream is =
> this.classLoader.getResourceAsStream(this.path);
> >>>>  +        if (is == null) {
> >>>>  +            throw new IOException(getName() + " does not
> >>> exist");
> >>>>  +        }
> >>>>  +        return is;
> >>>>  +    }
> >>>>  +
> >>>>  +    @Override
> >>>>  +    public URI toURI() throws IOException {
> >>>>  +        try {
> >>>>  +            return resolveURL().toURI();
> >>>>  +        } catch (URISyntaxException e) {
> >>>>  +            throw new IOException(e);
> >>>>  +        }
> >>>>  +    }
> >>>>  +
> >>>>  +    @Override
> >>>>  +    public long lastModified() throws IOException {
> >>>>  +        return 0;
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * This implementation returns the name current the file that
> this
> >>> class
> >>>>  path
> >>>>  +     * resource refers to.
> >>>>  +     */
> >>>>  +    @Override
> >>>>  +    public String getName() {
> >>>>  +        return "classpath:"+path;
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * This implementation returns a description that includes the
> class
> >>> path
> >>>>  location.
> >>>>  +     */
> >>>>  +    @Override
> >>>>  +    public String toString() {
> >>>>  +        return "ClassPathResource[" + path + ']';
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * This implementation compares the underlying class path
> locations.
> >>>>  +     */
> >>>>  +    @Override
> >>>>  +    public boolean equals(Object obj) {
> >>>>  +        if (obj == this) {
> >>>>  +            return true;
> >>>>  +        }
> >>>>  +        if (obj instanceof ClassPathResource) {
> >>>>  +            ClassPathResource otherRes = (ClassPathResource) obj;
> >>>>  +            return (this.path.equals(otherRes.path) &&
> >>>>  +                    Objects.equals(this.classLoader,
> >>> otherRes.classLoader));
> >>>>  +        }
> >>>>  +        return false;
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * This implementation returns the hash code current the
> underlying
> >>>>  +     * class path location.
> >>>>  +     */
> >>>>  +    @Override
> >>>>  +    public int hashCode() {
> >>>>  +        return getName().hashCode();
> >>>>  +    }
> >>>>  +
> >>>>  +}
> >>>>
> >>>>
> >>>
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
> >>>>
> ----------------------------------------------------------------------
> >>>>  diff --git
> >>>>
> >>>
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
> >>>
> >>>>
> >>>
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
> >>>>  new file mode 100644
> >>>>  index 0000000..eb56c1d
> >>>>  --- /dev/null
> >>>>  +++
> >>>>
> >>>
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
> >>>>  @@ -0,0 +1,93 @@
> >>>>  +/*
> >>>>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>>>  + * or more contributor license agreements.  See the NOTICE file
> >>>>  + * distributed with this work for additional information
> >>>>  + * regarding copyright ownership.  The ASF licenses this file
> >>>>  + * to you under the Apache License, Version 2.0 (the
> >>>>  + * "License"); you may not use this file except in compliance
> >>>>  + * with the License.  You may obtain a copy of the License at
> >>>>  + *
> >>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>>>  + *
> >>>>  + * Unless required by applicable law or agreed to in writing,
> >>>>  + * software distributed under the License is distributed on an
> >>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>>>  + * KIND, either express or implied.  See the License for the
> >>>>  + * specific language governing permissions and limitations
> >>>>  + * under the License.
> >>>>  + */
> >>>>  +package org.apache.tamaya.core.internal.resource;
> >>>>  +
> >>>>  +import org.apache.tamaya.core.resources.Resource;
> >>>>  +import org.apache.tamaya.core.resources.ResourceLoader;
> >>>>  +
> >>>>  +import javax.annotation.Priority;
> >>>>  +import java.io.File;
> >>>>  +import java.net.URL;
> >>>>  +import java.util.ArrayList;
> >>>>  +import java.util.Collection;
> >>>>  +import java.util.Enumeration;
> >>>>  +import java.util.List;
> >>>>  +import java.util.logging.Logger;
> >>>>  +
> >>>>  +/**
> >>>>  + * Simple default implementation of the resource loader, which does
> only
> >>>>  support direct references to files.
> >>>>  + */
> >>>>  +@Priority(0)
> >>>>  +public class DefaultResourceLoader implements ResourceLoader {
> >>>>  +
> >>>>  +    private static final Logger LOG =
> >>>>  Logger.getLogger(DefaultResourceLoader.class.getName());
> >>>>  +
> >>>>  +    @Override
> >>>>  +    public List<Resource> getResources(ClassLoader classLoader,
> >>>>  Collection<String> expressions) {
> >>>>  +        List<Resource> resources = new ArrayList<>();
> >>>>  +        for (String expression : expressions) {
> >>>>  +            if (tryClassPath(classLoader, expression, resources) ||
> >>>>  tryFile(expression, resources) ||
> >>>>  +                    tryURL(expression, resources)) {
> >>>>  +                continue;
> >>>>  +            }
> >>>>  +            LOG.warning("Failed to resolve resource: " +
> >>> expression);
> >>>>  +        }
> >>>>  +        return resources;
> >>>>  +    }
> >>>>  +
> >>>>  +    private boolean tryClassPath(ClassLoader classLoader, String
> >>> expression,
> >>>>  List<Resource> resources) {
> >>>>  +        try {
> >>>>  +            Enumeration<URL> urls =
> >>> classLoader.getResources(expression);
> >>>>  +            while (urls.hasMoreElements()) {
> >>>>  +                URL url = urls.nextElement();
> >>>>  +                resources.add(new URLResource(url));
> >>>>  +            }
> >>>>  +            return !resources.isEmpty();
> >>>>  +        } catch (Exception e) {
> >>>>  +            LOG.finest(() -> "Failed to load resource from CP:
> >>> " +
> >>>>  expression);
> >>>>  +        }
> >>>>  +        return false;
> >>>>  +    }
> >>>>  +
> >>>>  +    private boolean tryFile(String expression, List<Resource>
> >>> resources)
> >>>>  {
> >>>>  +        try {
> >>>>  +            File file = new File(expression);
> >>>>  +            if (file.exists()) {
> >>>>  +                resources.add(new FileResource(file));
> >>>>  +                return true;
> >>>>  +            }
> >>>>  +        } catch (Exception e) {
> >>>>  +            LOG.finest(() -> "Failed to load resource from file:
> >>> "
> >>>>  + expression);
> >>>>  +        }
> >>>>  +        return false;
> >>>>  +    }
> >>>>  +
> >>>>  +    private boolean tryURL(String expression, List<Resource>
> >>> resources)
> >>>>  {
> >>>>  +        try {
> >>>>  +            URL url = new URL(expression);
> >>>>  +            resources.add(new URLResource(url));
> >>>>  +            return true;
> >>>>  +        } catch (Exception e) {
> >>>>  +            LOG.finest(() -> "Failed to load resource from file:
> >>> "
> >>>>  + expression);
> >>>>  +        }
> >>>>  +        return false;
> >>>>  +
> >>>>  +    }
> >>>>  +
> >>>>  +}
> >>>>
> >>>>
> >>>
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
> >>>>
> ----------------------------------------------------------------------
> >>>>  diff --git
> >>>>
> >>>
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
> >>>>
> >>>
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
> >>>>  new file mode 100644
> >>>>  index 0000000..e0096e5
> >>>>  --- /dev/null
> >>>>  +++
> >>>>
> >>>
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
> >>>>  @@ -0,0 +1,162 @@
> >>>>  +/*
> >>>>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>>>  + * or more contributor license agreements.  See the NOTICE file
> >>>>  + * distributed with this work for additional information
> >>>>  + * regarding copyright ownership.  The ASF licenses this file
> >>>>  + * to you under the Apache License, Version 2.0 (the
> >>>>  + * "License"); you may not use this file except in compliance
> >>>>  + * with the License.  You may obtain a copy of the License at
> >>>>  + *
> >>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>>>  + *
> >>>>  + * Unless required by applicable law or agreed to in writing,
> >>>>  + * software distributed under the License is distributed on an
> >>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>>>  + * KIND, either express or implied.  See the License for the
> >>>>  + * specific language governing permissions and limitations
> >>>>  + * under the License.
> >>>>  + */
> >>>>  +package org.apache.tamaya.core.internal.resource;
> >>>>  +
> >>>>  +import org.apache.tamaya.core.resources.Resource;
> >>>>  +
> >>>>  +import java.io.File;
> >>>>  +import java.io.FileInputStream;
> >>>>  +import java.io.IOException;
> >>>>  +import java.io.InputStream;
> >>>>  +import java.net.URI;
> >>>>  +import java.util.Objects;
> >>>>  +
> >>>>  +/**
> >>>>  + * Implementation of {@link
> >>> org.apache.tamaya.core.resources.Resource} to
> >>>>  be loaded from a file.
> >>>>  + * @see java.io.File
> >>>>  + */
> >>>>  +public class FileResource implements Resource {
> >>>>  +
> >>>>  +    private final File file;
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Creates a new instance.
> >>>>  +     *
> >>>>  +     * @param file a File, not null.
> >>>>  +     */
> >>>>  +    public FileResource(File file) {
> >>>>  +        this.file = Objects.requireNonNull(file, "File must not be
> >>>>  null");
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Crreates a new instance.
> >>>>  +     *
> >>>>  +     * @param filePath a file path
> >>>>  +     */
> >>>>  +    public FileResource(String filePath) {
> >>>>  +        Objects.requireNonNull(filePath, "Path must not be
> >>> null");
> >>>>  +        this.file = new File(filePath);
> >>>>  +    }
> >>>>  +
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Get the file path for this resource.
> >>>>  +     */
> >>>>  +    public final String getPath() {
> >>>>  +        return this.file.getPath();
> >>>>  +    }
> >>>>  +
> >>>>  +
> >>>>  +    /**
> >>>>  +     * This implementation returns whether the underlying file
> exists.
> >>>>  +     *
> >>>>  +     * @see java.io.File#exists()
> >>>>  +     */
> >>>>  +    @Override
> >>>>  +    public boolean exists() {
> >>>>  +        return this.file.exists();
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * This implementation checks whether the underlying file is
> marked as
> >>>
> >>>>  readable
> >>>>  +     * (and corresponds to an actual file with content, not to a
> >>> directory).
> >>>>  +     *
> >>>>  +     * @see java.io.File#canRead()
> >>>>  +     * @see java.io.File#isDirectory()
> >>>>  +     */
> >>>>  +    @Override
> >>>>  +    public boolean isAccessible() {
> >>>>  +        return (this.file.canRead() && !this.file.isDirectory());
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * This implementation opens a FileInputStream for the
> underlying
> >>> file.
> >>>>  +     *
> >>>>  +     * @see java.io.FileInputStream
> >>>>  +     */
> >>>>  +    @Override
> >>>>  +    public InputStream getInputStream() throws IOException {
> >>>>  +        return new FileInputStream(this.file);
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * This implementation returns a URI for the underlying file.
> >>>>  +     *
> >>>>  +     * @see java.io.File#toURI()
> >>>>  +     */
> >>>>  +    @Override
> >>>>  +    public URI toURI() throws IOException {
> >>>>  +        return this.file.toURI();
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Returns the underlying File's length.
> >>>>  +     */
> >>>>  +    @Override
> >>>>  +    public long length() throws IOException {
> >>>>  +        return this.file.length();
> >>>>  +    }
> >>>>  +
> >>>>  +    @Override
> >>>>  +    public long lastModified() throws IOException {
> >>>>  +        return file.lastModified();
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Returns the name of the current file.
> >>>>  +     *
> >>>>  +     * @see java.io.File#getName()
> >>>>  +     */
> >>>>  +    @Override
> >>>>  +    public String getName() {
> >>>>  +        return this.file.getName();
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Returns a description that includes the absolute
> >>>>  +     * path of the current file.
> >>>>  +     *
> >>>>  +     * @see java.io.File#getAbsolutePath()
> >>>>  +     */
> >>>>  +    @Override
> >>>>  +    public String toString() {
> >>>>  +        return "File [" + this.file.getAbsolutePath() +
> >>>>  "]";
> >>>>  +    }
> >>>>  +
> >>>>  +
> >>>>  +    // implementation current WritableResource
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Compares the underlying Files.
> >>>>  +     */
> >>>>  +    @Override
> >>>>  +    public boolean equals(Object obj) {
> >>>>  +        return (obj == this ||
> >>>>  +                (obj instanceof FileResource &&
> >>>>  this.file.equals(((FileResource) obj).file)));
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Returns hash code current the underlying File reference.
> >>>>  +     */
> >>>>  +    @Override
> >>>>  +    public int hashCode() {
> >>>>  +        return this.file.hashCode();
> >>>>  +    }
> >>>>  +
> >>>>  +}
> >>>>
> >>>>
> >>>
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
> >>>>
> ----------------------------------------------------------------------
> >>>>  diff --git
> >>>>
> >>>
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
> >>>
> >>>>
> >>>
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
> >>>>  new file mode 100644
> >>>>  index 0000000..09510b4
> >>>>  --- /dev/null
> >>>>  +++
> >>>>
> >>>
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
> >>>>  @@ -0,0 +1,117 @@
> >>>>  +/*
> >>>>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>>>  + * or more contributor license agreements.  See the NOTICE file
> >>>>  + * distributed with this work for additional information
> >>>>  + * regarding copyright ownership.  The ASF licenses this file
> >>>>  + * to you under the Apache License, Version 2.0 (the
> >>>>  + * "License"); you may not use this file except in compliance
> >>>>  + * with the License.  You may obtain a copy of the License at
> >>>>  + *
> >>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>>>  + *
> >>>>  + * Unless required by applicable law or agreed to in writing,
> >>>>  + * software distributed under the License is distributed on an
> >>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>>>  + * KIND, either express or implied.  See the License for the
> >>>>  + * specific language governing permissions and limitations
> >>>>  + * under the License.
> >>>>  + */
> >>>>  +package org.apache.tamaya.core.internal.resource;
> >>>>  +
> >>>>  +import org.apache.tamaya.core.resources.Resource;
> >>>>  +
> >>>>  +import java.io.IOException;
> >>>>  +import java.io.InputStream;
> >>>>  +import java.net.URI;
> >>>>  +import java.util.Objects;
> >>>>  +
> >>>>  +/**
> >>>>  + * Simple Resource encapsulating an InputStream.
> >>>>  + */
> >>>>  +public class InputStreamResource implements Resource {
> >>>>  +
> >>>>  +    /** The InputStream. */
> >>>>  +    private final InputStream inputStream;
> >>>>  +    /** The read flag. */
> >>>>  +    private boolean read = false;
> >>>>  +    /** The name of the resource. */
> >>>>  +    private String name;
> >>>>  +
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Create a new InputStreamResource.
> >>>>  +     *
> >>>>  +     * @param inputStream the InputStream to use
> >>>>  +     */
> >>>>  +    public InputStreamResource(InputStream inputStream) {
> >>>>  +        this(inputStream, "InputStream:");
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Create a new InputStreamResource.
> >>>>  +     *
> >>>>  +     * @param inputStream the InputStream to use
> >>>>  +     * @param name where the InputStream comes from
> >>>>  +     */
> >>>>  +    public InputStreamResource(InputStream inputStream, String name)
> >>> {
> >>>>  +        this.inputStream = Objects.requireNonNull(inputStream);
> >>>>  +        this.name = (name != null ? name : "InputStream");
> >>>>  +    }
> >>>>  +
> >>>>  +
> >>>>  +    /**
> >>>>  +     * This implementation always returns {@code true}.
> >>>>  +     */
> >>>>  +    @Override
> >>>>  +    public boolean exists() {
> >>>>  +        return true;
> >>>>  +    }
> >>>>  +
> >>>>  +    @Override
> >>>>  +    public URI toURI() throws IOException {
> >>>>  +        throw new IOException("URI not available.");
> >>>>  +    }
> >>>>  +
> >>>>  +    @Override
> >>>>  +    public long lastModified() throws IOException {
> >>>>  +        throw new IOException("lastModified not available.");
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Accesses the input stream. Hereby the input stream can only
> >>> accessed
> >>>>  once.
> >>>>  +     */
> >>>>  +    @Override
> >>>>  +    public InputStream getInputStream() throws IOException {
> >>>>  +        if (this.read) {
> >>>>  +            throw new IllegalStateException("InputStream can only be
> >>> read
> >>>>  once!");
> >>>>  +        }
> >>>>  +        this.read = true;
> >>>>  +        return this.inputStream;
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * This implementation returns the passed-in description, if
> any.
> >>>>  +     */
> >>>>  +    public String toString() {
> >>>>  +        return this.name != null ? this.name : super.toString();
> >>>>  +    }
> >>>>  +
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Compares the underlying InputStream.
> >>>>  +     */
> >>>>  +    @Override
> >>>>  +    public boolean equals(Object obj) {
> >>>>  +        return (obj == this ||
> >>>>  +                (obj instanceof InputStreamResource &&
> >>>>  ((InputStreamResource) obj).inputStream.equals(this.inputStream)));
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * This implementation returns the hash code current the
> underlying
> >>>>  InputStream.
> >>>>  +     */
> >>>>  +    @Override
> >>>>  +    public int hashCode() {
> >>>>  +        return this.inputStream.hashCode();
> >>>>  +    }
> >>>>  +
> >>>>  +}
> >>>>
> >>>>
> >>>
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
> >>>>
> ----------------------------------------------------------------------
> >>>>  diff --git
> >>>>
> >>>
> a/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
> >>>>
> >>>
> b/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
> >>>>  new file mode 100644
> >>>>  index 0000000..4da6c53
> >>>>  --- /dev/null
> >>>>  +++
> >>>>
> >>>
> b/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
> >>>>  @@ -0,0 +1,37 @@
> >>>>  +/*
> >>>>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>>>  + * or more contributor license agreements.  See the NOTICE file
> >>>>  + * distributed with this work for additional information
> >>>>  + * regarding copyright ownership.  The ASF licenses this file
> >>>>  + * to you under the Apache License, Version 2.0 (the
> >>>>  + * "License"); you may not use this file except in compliance
> >>>>  + * with the License.  You may obtain a copy of the License at
> >>>>  + *
> >>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>>>  + *
> >>>>  + * Unless required by applicable law or agreed to in writing,
> >>>>  + * software distributed under the License is distributed on an
> >>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>>>  + * KIND, either express or implied.  See the License for the
> >>>>  + * specific language governing permissions and limitations
> >>>>  + * under the License.
> >>>>  + */
> >>>>  +package org.apache.tamaya.core.resources;
> >>>>  +
> >>>>  +import java.io.IOException;
> >>>>  +import java.io.InputStream;
> >>>>  +
> >>>>  +/**
> >>>>  + * Simple interface for a component that provides data based on an
> >>> InputStream.
> >>>>  + */
> >>>>  +@FunctionalInterface
> >>>>  +public interface InputStreamSupplier {
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Access the input stream.
> >>>>  +     * @return the input stream for use.
> >>>>  +     * @throws IOException i the input stream could not be obtained.
> >>>>  +     */
> >>>>  +    InputStream getInputStream() throws IOException;
> >>>>  +
> >>>>  +}
> >>>>
> >>>>
> >>>
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
> >>>>
> ----------------------------------------------------------------------
> >>>>  diff --git
> >>> a/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
> >>>>  b/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
> >>>>  new file mode 100644
> >>>>  index 0000000..31c679d
> >>>>  --- /dev/null
> >>>>  +++
> b/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
> >>>>  @@ -0,0 +1,115 @@
> >>>>  +/*
> >>>>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>>>  + * or more contributor license agreements.  See the NOTICE file
> >>>>  + * distributed with this work for additional information
> >>>>  + * regarding copyright ownership.  The ASF licenses this file
> >>>>  + * to you under the Apache License, Version 2.0 (the
> >>>>  + * "License"); you may not use this file except in compliance
> >>>>  + * with the License.  You may obtain a copy of the License at
> >>>>  + *
> >>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>>>  + *
> >>>>  + * Unless required by applicable law or agreed to in writing,
> >>>>  + * software distributed under the License is distributed on an
> >>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>>>  + * KIND, either express or implied.  See the License for the
> >>>>  + * specific language governing permissions and limitations
> >>>>  + * under the License.
> >>>>  + */
> >>>>  +package org.apache.tamaya.core.resources;
> >>>>  +
> >>>>  +import java.io.File;
> >>>>  +import java.io.IOException;
> >>>>  +import java.io.InputStream;
> >>>>  +import java.net.URI;
> >>>>  +import java.net.URL;
> >>>>  +import java.util.Objects;
> >>>>  +
> >>>>  +/**
> >>>>  + * Interface for an abstract resource. The effective resource
> >>> implementation
> >>>>  can be completely arbitrary.
> >>>>  + * By default files, classpath resources and URLs are supported, but
> >>> alternate
> >>>>  implementations are possible.
> >>>>  + *
> >>>>  + * @see #getInputStream()
> >>>>  + * @see #toURI()
> >>>>  + */
> >>>>  +public interface Resource extends InputStreamSupplier {
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Return whether this resource actually exists. Depending on
> the
> >>> resource
> >>>>  this can delegate to
> >>>>  +     * {@link java.io.File#exists()} or whatever may be appropriate
> >>> to
> >>>>  check accessibility of the resource.
> >>>>  +     */
> >>>>  +    default boolean exists() {
> >>>>  +        // Try to open a file first, if that fails try to open the
> >>> stream...
> >>>>  +        try {
> >>>>  +            return new File(toURI()).exists();
> >>>>  +        } catch (IOException ex) {
> >>>>  +            // Fallback
> >>>>  +            try {
> >>>>  +                InputStream is = getInputStream();
> >>>>  +                is.close();
> >>>>  +                return true;
> >>>>  +            } catch (Exception e) {
> >>>>  +                // ignore, just return false for non existing
> >>>>  +                return false;
> >>>>  +            }
> >>>>  +        }
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Checks whether the resource is accessible, meaning {@link
> >>>>  #getInputStream()} should return a InputStream for reading the
> >>>>  +     * resource's content.
> >>>>  +     *
> >>>>  +     * @see #getInputStream()
> >>>>  +     */
> >>>>  +    default boolean isAccessible() {
> >>>>  +        return true;
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Returns the resource as an URI.
> >>>>  +     *
> >>>>  +     * @throws IOException if the resource cannot be resolved as
> URI.
> >>>>  +     */
> >>>>  +    URI toURI() throws IOException;
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Determines the length for this resource.
> >>>>  +     *
> >>>>  +     * @throws IOException if the resource is not readable.
> >>>>  +     */
> >>>>  +    default long length() throws IOException {
> >>>>  +        try(InputStream is = this.getInputStream();) {
> >>>>  +            Objects.requireNonNull(is, "resource not
> >>> available");
> >>>>  +            long length = 0;
> >>>>  +            byte[] buf = new byte[256];
> >>>>  +            int bytesRead;
> >>>>  +            while ((bytesRead = is.read(buf)) > 0) {
> >>>>  +                length += bytesRead;
> >>>>  +            }
> >>>>  +            return length;
> >>>>  +        }
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Determine the last-modified timestamp for a resource, as UTC
> ms
> >>>>  timestamp
> >>>>  +     *
> >>>>  +     * @throws IOException if the resource is not accessible.
> >>>>  +     */
> >>>>  +    default long lastModified() throws IOException{
> >>>>  +        return new File(toURI()).lastModified();
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Get a name for the resource. The name should be identifying
> the
> >>> resource
> >>>>  and also
> >>>>  +     * never change, so it must be eligible for hashcode/equals
> >>>>  implementations.
> >>>>  +     */
> >>>>  +    default String getName() {
> >>>>  +        try {
> >>>>  +            return toURI().toString();
> >>>>  +        } catch (Exception e) {
> >>>>  +            return toString();
> >>>>  +        }
> >>>>  +    }
> >>>>  +
> >>>>  +
> >>>>  +}
> >>>>  \ No newline at end of file
> >>>>
> >>>>
> >>>
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
> >>>>
> ----------------------------------------------------------------------
> >>>>  diff --git
> >>>>
> a/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
> >>>>
> b/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
> >>>>  new file mode 100644
> >>>>  index 0000000..5aff10a
> >>>>  --- /dev/null
> >>>>  +++
> >>>
> b/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
> >>>>  @@ -0,0 +1,91 @@
> >>>>  +/*
> >>>>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>>>  + * or more contributor license agreements.  See the NOTICE file
> >>>>  + * distributed with this work for additional information
> >>>>  + * regarding copyright ownership.  The ASF licenses this file
> >>>>  + * to you under the Apache License, Version 2.0 (the
> >>>>  + * "License"); you may not use this file except in compliance
> >>>>  + * with the License.  You may obtain a copy of the License at
> >>>>  + *
> >>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>>>  + *
> >>>>  + * Unless required by applicable law or agreed to in writing,
> >>>>  + * software distributed under the License is distributed on an
> >>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>>>  + * KIND, either express or implied.  See the License for the
> >>>>  + * specific language governing permissions and limitations
> >>>>  + * under the License.
> >>>>  + */
> >>>>  +package org.apache.tamaya.core.resources;
> >>>>  +
> >>>>  +import java.util.Arrays;
> >>>>  +import java.util.Collection;
> >>>>  +import java.util.List;
> >>>>  +
> >>>>  +/**
> >>>>  + * Interface to be implemented by modules. By default only direct
> >>> file/resource
> >>>>  resolution is supported, whereas
> >>>>  + * extension modules may add functionality to perform ant styled
> pattern
> >>>>  resolution of resources.
> >>>>  + */
> >>>>  +public interface ResourceLoader {
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Resolves resource expressions to a list of {@link
> >>>>  org.apache.tamaya.core.resources.Resource}s. Hereby
> >>>>  +     * the ordering of resources matches the input of the resolved
> >>> expressions.
> >>>>  Nevertheless be aware that
> >>>>  +     * there is no determined ordering of resources located within a
> >>>>  classloader.
> >>>>  +     *
> >>>>  +     * @param expressions the expressions to be resolved, not empty.
> >>>>  +     * @return the corresponding collection of current {@link
> >>>>  org.apache.tamaya.core.resources.Resource}s found, never
> >>>>  +     * null.
> >>>>  +     * .
> >>>>  +     */
> >>>>  +    default Collection<Resource>
> >>> getResources(Collection<String>
> >>>>  expressions) {
> >>>>  +        ClassLoader cl =
> Thread.currentThread().getContextClassLoader();
> >>>>  +        if (cl == null) {
> >>>>  +            cl = getClass().getClassLoader();
> >>>>  +        }
> >>>>  +        return getResources(cl, expressions);
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Resolves resource expressions to a list of {@link
> >>>>  org.apache.tamaya.core.resources.Resource}s. Hereby
> >>>>  +     * the ordering of resources matches the input of the resolved
> >>> expressions.
> >>>>  Nevertheless be aware that
> >>>>  +     * there is no determined ordering of resources located within a
> >>>>  classloader.
> >>>>  +     *
> >>>>  +     * @param expressions the expressions to be resolved, not empty.
> >>>>  +     * @return the corresponding collection of current {@link
> >>>>  org.apache.tamaya.core.resources.Resource}s found, never
> >>>>  +     * null.
> >>>>  +     * .
> >>>>  +     */
> >>>>  +    default Collection<Resource> getResources(String... expressions)
> >>>
> >>>>  {
> >>>>  +        return getResources(Arrays.asList(expressions));
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Resolves resource expressions to a list of {@link
> >>>>  org.apache.tamaya.core.resources.Resource}s, considerubg
> >>>>  +     * the given classloader for classloader dependent resources.
> Hereby
> >>>>  +     * the ordering of resources matches the input of the resolved
> >>> expressions.
> >>>>  Nevertheless be aware that
> >>>>  +     * there is no determined ordering of resources located within a
> >>>>  classloader.
> >>>>  +     *
> >>>>  +     * @param expressions the expressions to be resolved, not empty.
> >>>>  +     * @return the corresponding collection of current {@link
> >>>>  org.apache.tamaya.core.resources.Resource}s found, never
> >>>>  +     * null.
> >>>>  +     * .
> >>>>  +     */
> >>>>  +    default Collection<Resource> getResources(ClassLoader
> >>> classLoader,
> >>>>  String... expressions){
> >>>>  +        return getResources(classLoader,
> Arrays.asList(expressions));
> >>>>  +    }
> >>>>  +
> >>>>  +    /**
> >>>>  +     * Resolves resource expressions to a list of {@link
> >>>>  org.apache.tamaya.core.resources.Resource}s, considerubg
> >>>>  +     * the given classloader for classloader dependent resources.
> Hereby
> >>>>  +     * the ordering of resources matches the input of the resolved
> >>> expressions.
> >>>>  Nevertheless be aware that
> >>>>  +     * there is no determined ordering of resources located within a
> >>>>  classloader.
> >>>>  +     *
> >>>>  +     * @param expressions the expressions to be resolved, not empty.
> >>>>  +     * @return the corresponding collection of current {@link
> >>>>  org.apache.tamaya.core.resources.Resource}s found, never
> >>>>  +     * null.
> >>>>  +     * .
> >>>>  +     */
> >>>>  +    Collection<Resource> getResources(ClassLoader classLoader,
> >>>>  Collection<String> expressions);
> >>>>  +
> >>>>  +}
> >>>>
> >>>>
> >>>
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> >>>>
> ----------------------------------------------------------------------
> >>>>  diff --git
> >>> a/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> >>>>  b/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> >>>>  index be1eadb..9c7b894 100644
> >>>>  ---
> a/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> >>>>  +++
> b/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> >>>>  @@ -41,6 +41,12 @@ public class ConfigurationTest {
> >>>>           assertEquals("Lukas",
> >>>>  Configuration.current().get("name3").get());  // oderridden
> >>> default
> >>>>           assertEquals("Sereina",
> >>>>  Configuration.current().get("name4").get()); // final only
> >>>>           assertEquals("Benjamin",
> >>>>  Configuration.current().get("name5").get()); // final only
> >>>>  +
> >>>>  +        System.out.println("name : " +
> >>>>  Configuration.current().get("name").get());
> >>>>  +        System.out.println("name2: " +
> >>>>  Configuration.current().get("name2").get());
> >>>>  +        System.out.println("name3: " +
> >>>>  Configuration.current().get("name3").get());
> >>>>  +        System.out.println("name4: " +
> >>>>  Configuration.current().get("name4").get());
> >>>>  +        System.out.println("name5: " +
> >>>>  Configuration.current().get("name5").get());
> >>>>       }
> >>>>
> >>>>
> >>>>
> >>>>
> >>>
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
> >>>>
> ----------------------------------------------------------------------
> >>>>  diff --git
> >>>>
> >>>
> a/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
> >>>
> >>>>
> >>>
> b/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
> >>>>  deleted file mode 100644
> >>>>  index 51cc2dc..0000000
> >>>>  ---
> >>>>
> >>>
> a/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
> >>>>  +++ /dev/null
> >>>>  @@ -1,70 +0,0 @@
> >>>>  -/*
> >>>>  - * Licensed to the Apache Software Foundation (ASF) under one
> >>>>  - * or more contributor license agreements.  See the NOTICE file
> >>>>  - * distributed with this work for additional information
> >>>>  - * regarding copyright ownership.  The ASF licenses this file
> >>>>  - * to you under the Apache License, Version 2.0 (the
> >>>>  - * "License"); you may not use this file except in compliance
> >>>>  - * with the License.  You may obtain a copy of the License at
> >>>>  - *
> >>>>  - * http://www.apache.org/licenses/LICENSE-2.0
> >>>>  - *
> >>>>  - * Unless required by applicable law or agreed to in writing,
> >>>>  - * software distributed under the License is distributed on an
> >>>>  - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>>>  - * KIND, either express or implied.  See the License for the
> >>>>  - * specific language governing permissions and limitations
> >>>>  - * under the License.
> >>>>  - */
> >>>>  -package org.apache.tamaya.core.test.propertysource;
> >>>>  -
> >>>>  -import org.apache.tamaya.core.propertysource.DefaultOrdinal;
> >>>>  -import
> org.apache.tamaya.core.propertysource.EnvironmentPropertySource;
> >>>>  -import org.junit.Assert;
> >>>>  -import org.junit.Test;
> >>>>  -
> >>>>  -import java.util.Map;
> >>>>  -import java.util.Optional;
> >>>>  -
> >>>>  -public class EnvironmentPropertySourceTest {
> >>>>  -
> >>>>  -    private EnvironmentPropertySource propertySource = new
> >>>>  EnvironmentPropertySource();
> >>>>  -
> >>>>  -
> >>>>  -    @Test
> >>>>  -    public void testGetOrdinal() {
> >>>>  -        Assert.assertEquals(DefaultOrdinal.ENVIRONMENT_PROPERTIES,
> >>>>  propertySource.getOrdinal());
> >>>>  -    }
> >>>>  -
> >>>>  -    @Test
> >>>>  -    public void testGet() {
> >>>>  -        String environmentPropertyToCheck =
> >>>>  System.getenv().keySet().iterator().next();
> >>>>  -
> >>>>  -        Optional<String> value =
> >>>>  propertySource.get(environmentPropertyToCheck);
> >>>>  -        Assert.assertTrue(value.isPresent());
> >>>>  -
> Assert.assertEquals(System.getenv(environmentPropertyToCheck),
> >>>>  value.get());
> >>>>  -    }
> >>>>  -
> >>>>  -    @Test
> >>>>  -    public void testGetProperties() {
> >>>>  -        Map<String, String> environmentProperties = System.getenv();
> >>>>  -
> >>>>  -        Assert.assertEquals(environmentProperties.size(),
> >>>>  propertySource.getProperties().size());
> >>>>  -
> >>>>  -        for (Map.Entry<String, String> propertySourceEntry :
> >>>>  propertySource.getProperties().entrySet()) {
> >>>>  -            Assert.assertEquals("Entry values for key '" +
> >>>>  propertySourceEntry.getKey() + "' do not match",
> >>>>  -
> >>>>  environmentProperties.get(propertySourceEntry.getKey()),
> >>>>  propertySourceEntry.getValue());
> >>>>  -        }
> >>>>  -
> >>>>  -        // modification is not allowed
> >>>>  -        try {
> >>>>  -            propertySource.getProperties().put("add.new.keys",
> >>>>  "must throw exception");
> >>>>  -
> Assert.fail(UnsupportedOperationException.class.getName() +
> >>> "
> >>>>  expected");
> >>>>  -        }
> >>>>  -        catch (UnsupportedOperationException e) {
> >>>>  -            // expected -> all is fine
> >>>>  -        }
> >>>>  -    }
> >>>>  -
> >>>>  -
> >>>>  -}
> >>>>
> >>>>
> >>>
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
> >>>>
> ----------------------------------------------------------------------
> >>>>  diff --git
> >>>>
> >>>
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
> >>>
> >>>>
> >>>
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
> >>>>  new file mode 100644
> >>>>  index 0000000..5fa90b1
> >>>>  --- /dev/null
> >>>>  +++
> >>>>
> >>>
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
> >>>>  @@ -0,0 +1,32 @@
> >>>>  +/*
> >>>>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>>>  + * or more contributor license agreements.  See the NOTICE file
> >>>>  + * distributed with this work for additional information
> >>>>  + * regarding copyright ownership.  The ASF licenses this file
> >>>>  + * to you under the Apache License, Version 2.0 (the
> >>>>  + * "License"); you may not use this file except in compliance
> >>>>  + * with the License.  You may obtain a copy of the License at
> >>>>  + *
> >>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>>>  + *
> >>>>  + * Unless required by applicable law or agreed to in writing,
> >>>>  + * software distributed under the License is distributed on an
> >>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>>>  + * KIND, either express or implied.  See the License for the
> >>>>  + * specific language governing permissions and limitations
> >>>>  + * under the License.
> >>>>  + */
> >>>>  +package org.apache.tamaya.core.testdata;
> >>>>  +
> >>>>  +import org.apache.tamaya.core.PathBasedPropertySourceProvider;
> >>>>  +import org.apache.tamaya.core.formats.PropertiesFormat;
> >>>>  +
> >>>>  +/**
> >>>>  + * Test provider reading properties from
> >>> classpath:cfg/defaults/**.properties.
> >>>>  + */
> >>>>  +public class TestPropertyDefaultSourceProvider extends
> >>>>  PathBasedPropertySourceProvider{
> >>>>  +
> >>>>  +    public TestPropertyDefaultSourceProvider() {
> >>>>  +        super("default-testdata-properties", new
> >>>>  PropertiesFormat(100), "classpath:cfg/defaults/**/*.properties");
> >>>>  +    }
> >>>>  +}
> >>>>
> >>>>
> >>>
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
> >>>>
> ----------------------------------------------------------------------
> >>>>  diff --git
> >>>>
> >>>
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
> >>>>
> >>>
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
> >>>>  deleted file mode 100644
> >>>>  index d1314aa..0000000
> >>>>  ---
> >>>
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
> >>>>  +++ /dev/null
> >>>>  @@ -1,55 +0,0 @@
> >>>>  -/*
> >>>>  - * Licensed to the Apache Software Foundation (ASF) under one
> >>>>  - * or more contributor license agreements.  See the NOTICE file
> >>>>  - * distributed with this work for additional information
> >>>>  - * regarding copyright ownership.  The ASF licenses this file
> >>>>  - * to you under the Apache License, Version 2.0 (the
> >>>>  - * "License"); you may not use this file except in compliance
> >>>>  - * with the License.  You may obtain a copy of the License at
> >>>>  - *
> >>>>  - *  http://www.apache.org/licenses/LICENSE-2.0
> >>>>  - *
> >>>>  - * Unless required by applicable law or agreed to in writing,
> >>>>  - * software distributed under the License is distributed on an
> >>>>  - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>>>  - * KIND, either express or implied.  See the License for the
> >>>>  - * specific language governing permissions and limitations
> >>>>  - * under the License.
> >>>>  - */
> >>>>  -package org.apache.tamaya.core.testdata;
> >>>>  -
> >>>>  -import java.util.HashMap;
> >>>>  -import java.util.Map;
> >>>>  -
> >>>>  -import org.apache.tamaya.core.propertysource.BasePropertySource;
> >>>>  -
> >>>>  -/**
> >>>>  - * Test provider reading properties from
> >>> classpath:cfg/final/**.properties.
> >>>>  - */
> >>>>  -public class TestPropertySource extends BasePropertySource {
> >>>>  -
> >>>>  -    private static final Map<String, String> VALUES;
> >>>>  -    static {
> >>>>  -        VALUES = new HashMap<String, String>();
> >>>>  -        VALUES.put("name", "Robin");
> >>>>  -        VALUES.put("name2", "Sabine");
> >>>>  -        VALUES.put("name3", "Lukas");
> >>>>  -        VALUES.put("name4", "Sereina");
> >>>>  -        VALUES.put("name5", "Benjamin");
> >>>>  -    }
> >>>>  -
> >>>>  -
> >>>>  -    public TestPropertySource() {
> >>>>  -        initialzeOrdinal(100);
> >>>>  -    }
> >>>>  -
> >>>>  -    @Override
> >>>>  -    public String getName() {
> >>>>  -        return "TestPropertySource";
> >>>>  -    }
> >>>>  -
> >>>>  -    @Override
> >>>>  -    public Map<String, String> getProperties() {
> >>>>  -        return VALUES;
> >>>>  -    }
> >>>>  -}
> >>>>
> >>>>
> >>>
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
> >>>>
> ----------------------------------------------------------------------
> >>>>  diff --git
> >>>>
> >>>
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
> >>>
> >>>>
> >>>
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
> >>>>  new file mode 100644
> >>>>  index 0000000..beafbf9
> >>>>  --- /dev/null
> >>>>  +++
> >>>>
> >>>
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
> >>>>  @@ -0,0 +1,32 @@
> >>>>  +/*
> >>>>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>>>  + * or more contributor license agreements.  See the NOTICE file
> >>>>  + * distributed with this work for additional information
> >>>>  + * regarding copyright ownership.  The ASF licenses this file
> >>>>  + * to you under the Apache License, Version 2.0 (the
> >>>>  + * "License"); you may not use this file except in compliance
> >>>>  + * with the License.  You may obtain a copy of the License at
> >>>>  + *
> >>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>>>  + *
> >>>>  + * Unless required by applicable law or agreed to in writing,
> >>>>  + * software distributed under the License is distributed on an
> >>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>>>  + * KIND, either express or implied.  See the License for the
> >>>>  + * specific language governing permissions and limitations
> >>>>  + * under the License.
> >>>>  + */
> >>>>  +package org.apache.tamaya.core.testdata;
> >>>>  +
> >>>>  +import org.apache.tamaya.core.PathBasedPropertySourceProvider;
> >>>>  +import org.apache.tamaya.core.formats.PropertiesFormat;
> >>>>  +
> >>>>  +/**
> >>>>  + * Test provider reading properties from
> >>> classpath:cfg/final/**.properties.
> >>>>  + */
> >>>>  +public class TestPropertySourceProvider extends
> >>>>  PathBasedPropertySourceProvider{
> >>>>  +
> >>>>  +    public TestPropertySourceProvider() {
> >>>>  +        super("final-testdata-properties", new
> >>> PropertiesFormat(200),
> >>>>  "classpath:cfg/final/**/*.properties");
> >>>>  +    }
> >>>>  +}
> >>>>
> >>>>
> >>>
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
> >>>>
> ----------------------------------------------------------------------
> >>>>  diff --git
> >>>>
> >>>
> a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
> >>>
> >>>>
> >>>
> b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
> >>>>  deleted file mode 100644
> >>>>  index e6f7fad..0000000
> >>>>  ---
> >>>>
> >>>
> a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
> >>>>  +++ /dev/null
> >>>>  @@ -1,19 +0,0 @@
> >>>>  -#
> >>>>  -# Licensed to the Apache Software Foundation (ASF) under one
> >>>>  -# or more contributor license agreements.  See the NOTICE file
> >>>>  -# distributed with this work for additional information
> >>>>  -# regarding copyright ownership.  The ASF licenses this file
> >>>>  -# to you under the Apache License, Version 2.0 (the
> >>>>  -# "License"); you may not use this file except in compliance
> >>>>  -# with the License.  You may obtain a copy current the License at
> >>>>  -#
> >>>>  -#    http://www.apache.org/licenses/LICENSE-2.0
> >>>>  -#
> >>>>  -# Unless required by applicable law or agreed to in writing,
> >>>>  -# software distributed under the License is distributed on an
> >>>>  -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>>>  -# KIND, either express or implied.  See the License for the
> >>>>  -# specific language governing permissions and limitations
> >>>>  -# under the License.
> >>>>  -#
> >>>>  -org.apache.tamaya.core.testdata.TestPropertySource
> >>>>  \ No newline at end of file
> >>>>
> >>>>
> >>>
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
> >>>>
> ----------------------------------------------------------------------
> >>>>  diff --git
> >>>>
> >>>
> a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
> >>>
> >>>>
> >>>
> b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
> >>>>  new file mode 100644
> >>>>  index 0000000..9db0ef4
> >>>>  --- /dev/null
> >>>>  +++
> >>>>
> >>>
> b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
> >>>>  @@ -0,0 +1,20 @@
> >>>>  +#
> >>>>  +# Licensed to the Apache Software Foundation (ASF) under one
> >>>>  +# or more contributor license agreements.  See the NOTICE file
> >>>>  +# distributed with this work for additional information
> >>>>  +# regarding copyright ownership.  The ASF licenses this file
> >>>>  +# to you under the Apache License, Version 2.0 (the
> >>>>  +# "License"); you may not use this file except in compliance
> >>>>  +# with the License.  You may obtain a copy current the License at
> >>>>  +#
> >>>>  +#    http://www.apache.org/licenses/LICENSE-2.0
> >>>>  +#
> >>>>  +# Unless required by applicable law or agreed to in writing,
> >>>>  +# software distributed under the License is distributed on an
> >>>>  +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>>>  +# KIND, either express or implied.  See the License for the
> >>>>  +# specific language governing permissions and limitations
> >>>>  +# under the License.
> >>>>  +#
> >>>>  +org.apache.tamaya.core.testdata.TestPropertyDefaultSourceProvider
> >>>>  +org.apache.tamaya.core.testdata.TestPropertySourceProvider
> >>>>  \ No newline at end of file
> >>>>
> >>>
> >>
> >
> >
>

Re: [2/4] incubator-tamaya git commit: TAMAYA-42, 43, 44: Readded non Spring related parts. Simplified resource API. Readded other tests.

Posted by Mark Struberg <st...@yahoo.de>.
>Spring logic is more advanced - and broken IMO. 
Totally agree. This was always targeted to allow configuration from inside the Spring XML files. This is essentially scripting. But we don't have this.
>This means all classloader usages would be excluded.

No, it's perfectly fine to have _some_ PropertySources who read up values from the ClassPath. Those are default configs for the app. And this also allows some kind of flexible application approach like just adding a jar and overriding some of it's configuration values in your own project.

Of course there are also PropertySources (JNDI, env and system by default but you could also add your own very easily) who don't rely on the ClassPath but 'inject' information from outside the application (ops, database, etc - whatever you like). And those PropertySources have a higher ordinal than the property files from your classpath.


> If this is accepted you only need to be able to provide an URL 
> to an existing source to be able to read it so format is the source
> if it has an URL constructor which makes thing really easier IMO.


That could be fine. If I understood you correctly then you would add a 'BasePropertySource' (better name needed ofc). which is in the spi package of our api module? And it has a constructor with the URL it should read? Or did I get this wrong?

LieGrue,
strub


On Sunday, 4 January 2015, 10:15, Romain Manni-Bucau <rm...@gmail.com> wrote:
>
>Spring logic is more advanced - and broken IMO. It can read from a particular jar depending syntax and where it is read from.
>It brings me to the first question we should have tackled: what is a config? For me it is all values which can be hardcoded and then cant be packaged inside the app - otherwise you break the predicate "i dont need to update my app for a config update". This means all classloader usages would be excluded. If this is accepted you only need to be able to provide an URL to an existing source to be able to read it so format is the source if it has an URL constructor which makes thing really easier IMO.
>Wdyt?
>
>Le 4 janv. 2015 10:09, "Mark Struberg" <st...@yahoo.de> a écrit :
>
>I just became aware that maybe my VOTE was not clear enough.
>>
>>> 2.) Wouldn't it be easier to write the functionality ourselves
>>> and be able to only implement the pieces we really need?
>>> Currently all we need is ClassLoader.getResources() and be done.
>>
>>My aim was not to implement ALL the functionality originally taken from Spring but really only the things we need.
>>And essentially the following:
>>
>>> Currently all we need is ClassLoader.getResources() and be done.
>>
>>
>>Reading Properties from a resource is essentially a single line of code:
>>
>>
>>java.util.Properties.load(ClassLoader.getResource(fileUrl).openStream());
>>
>>I don't yet get the benefit of the other code. Please explain.
>>
>>
>>LieGrue,
>>strub
>>
>>
>>
>>
>>
>>> On Sunday, 4 January 2015, 9:10, Mark Struberg <st...@yahoo.de> wrote:
>>> > Anatole, WHY do we need all of this?
>>>
>>> It is NOWHERE used!
>>>
>>> Why do we add 21 classes which don't provide anything useful to the project?
>>> There was even a VOTE that we should keep it simple and just do the things we
>>> need.
>>>
>>> I really don't get it. Is our goal to create a lightweight but flexible
>>> configuration system or is our goal to become big and fat?
>>>
>>>
>>> Maybe it makes sense but if so then please explain it to us.
>>>
>>>
>>> 1.) Why do we read in a specific format?
>>>
>>> All the system is handling String/String and only in the last step it *probably*
>>> gets converted into a target Type. I fail to see the benefit. Please explain it
>>> to us.
>>>
>>> 2.) Why do we need all the Resource implementations?
>>>
>>> Java provides Resource handling out of the box. Again: we don't need any
>>> scripting. So why add some handling for dynamic scenarios which we do not have?
>>> This is basically a copy of Spring.io. But we simply don't have anything
>>> scripted in XML as Spring does. So why should we add it?
>>>
>>>
>>> I'm really tired of seeing code all over the place which is not helpful for
>>> the project. Please don't add things we don't really need.
>>>
>>>
>>> LieGrue,
>>> strub
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>>  On Sunday, 4 January 2015, 2:52, "anatole@apache.org"
>>> <an...@apache.org> wrote:
>>>>  >T AMAYA-42,43,44: Readded non Spring related parts. Simplified resource
>>> API.
>>>>  Readded other tests.
>>>>
>>>>
>>>>  Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo
>>>>  Commit:
>>> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/cc237eb4
>>>>  Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/cc237eb4
>>>>  Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/cc237eb4
>>>>
>>>>  Branch: refs/heads/master
>>>>  Commit: cc237eb41b7d0c660261f451f47bbf07b7770c46
>>>>  Parents: 59a9e21
>>>>  Author: anatole <an...@apache.org>
>>>>  Authored: Sun Jan 4 02:17:56 2015 +0100
>>>>  Committer: anatole <an...@apache.org>
>>>>  Committed: Sun Jan 4 02:26:23 2015 +0100
>>>>
>>>>  ----------------------------------------------------------------------
>>>>  .../org/apache/tamaya/spi/PropertyFilter.java   |  10 +-
>>>>  .../core/PathBasedPropertySourceProvider.java   |  93 ++++++++++
>>>>  .../core/ResourcePropertySourceProvider.java    | 102 +++++++++++
>>>>  .../core/formats/ConfigurationFormat.java       |  53 ++++++
>>>>  .../tamaya/core/formats/PropertiesFormat.java   | 114 ++++++++++++
>>>>  .../core/formats/PropertiesXmlFormat.java       | 115 ++++++++++++
>>>>  .../core/internal/DefaultConfiguration.java     |  27 ++-
>>>>  .../internal/resource/ClassPathResource.java    | 178 +++++++++++++++++++
>>>>  .../resource/DefaultResourceLoader.java         |  93 ++++++++++
>>>>  .../core/internal/resource/FileResource.java    | 162 +++++++++++++++++
>>>>  .../internal/resource/InputStreamResource.java  | 117 ++++++++++++
>>>>  .../core/resources/InputStreamSupplier.java     |  37 ++++
>>>>  .../apache/tamaya/core/resources/Resource.java  | 115 ++++++++++++
>>>>  .../tamaya/core/resources/ResourceLoader.java   |  91 ++++++++++
>>>>  .../apache/tamaya/core/ConfigurationTest.java   |   6 +
>>>>  .../EnvironmentPropertySourceTest.java          |  70 --------
>>>>  .../TestPropertyDefaultSourceProvider.java      |  32 ++++
>>>>  .../core/testdata/TestPropertySource.java       |  55 ------
>>>>  .../testdata/TestPropertySourceProvider.java    |  32 ++++
>>>>  .../org.apache.tamaya.spi.PropertySource        |  19 --
>>>>  ...org.apache.tamaya.spi.PropertySourceProvider |  20 +++
>>>>  21 files changed, 1388 insertions(+), 153 deletions(-)
>>>>  ----------------------------------------------------------------------
>>>>
>>>>
>>>>
>>> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
>>>>  ----------------------------------------------------------------------
>>>>  diff --git a/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
>>>>  b/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
>>>>  index 7479008..c8626fc 100644
>>>>  --- a/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
>>>>  +++ b/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
>>>>  @@ -19,7 +19,7 @@
>>>>  package org.apache.tamaya.spi;
>>>>
>>>>
>>>>  -import java.util.Map;
>>>>  +import java.util.function.Function;
>>>>
>>>>  /**
>>>>    * <p>Interface for filtering the current map of properties during
>>> the
>>>>  evaluation of the chain of PropertySources.
>>>>  @@ -27,7 +27,7 @@ import java.util.Map;
>>>>    * hereby is defined by the corresponding {@code @Priority}
>>>>  annotation.</p>
>>>>    * <p>Filters </p>
>>>>    */
>>>>  -public interface PropertyFilter<T>{
>>>>  +public interface PropertyFilter{
>>>>
>>>>       /**
>>>>        * <p>Maps the current {@code valueToBeFiltered} value to a
>>> new
>>>>  value. The resulting value will be used as the result
>>>>  @@ -44,10 +44,10 @@ public interface PropertyFilter<T>{
>>>>        *
>>>>        * @param key the key accessed, not null.
>>>>        * @param valueToBeFiltered the value to be filtered, not null.
>>>>  -     * @param currentMap the current input property map, not null. Can be
>>> used
>>>>  for resolution of the filtered value
>>>>  -     *                   or as datasource for additional meta-information,
>>> such
>>>>  as categories, sensitivity etc.
>>>>  +     * @param propertyValueProvider accessor for reading additional (eg
>>>>  metadata) properties to perform correct
>>>>  +     *                              filtering, never null.
>>>>        * @return the filtered map, never null.
>>>>        */
>>>>  -    String filterProperty(String key, String valueToBeFiltered,
>>>>  Map<String,String> currentMap);
>>>>  +    String filterProperty(String key, String valueToBeFiltered,
>>>>  Function<String,String> propertyValueProvider);
>>>>
>>>>  }
>>>>
>>>>
>>> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
>>>>  ----------------------------------------------------------------------
>>>>  diff --git
>>>>
>>> a/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
>>>
>>>>
>>> b/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
>>>>  new file mode 100644
>>>>  index 0000000..31dbf4b
>>>>  --- /dev/null
>>>>  +++
>>>>
>>> b/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
>>>>  @@ -0,0 +1,93 @@
>>>>  +/*
>>>>  + * Licensed to the Apache Software Foundation (ASF) under one
>>>>  + * or more contributor license agreements.  See the NOTICE file
>>>>  + * distributed with this work for additional information
>>>>  + * regarding copyright ownership.  The ASF licenses this file
>>>>  + * to you under the Apache License, Version 2.0 (the
>>>>  + * "License"); you may not use this file except in compliance
>>>>  + * with the License.  You may obtain a copy of the License at
>>>>  + *
>>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
>>>>  + *
>>>>  + * Unless required by applicable law or agreed to in writing,
>>>>  + * software distributed under the License is distributed on an
>>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>>>  + * KIND, either express or implied.  See the License for the
>>>>  + * specific language governing permissions and limitations
>>>>  + * under the License.
>>>>  + */
>>>>  +package org.apache.tamaya.core;
>>>>  +
>>>>  +import org.apache.tamaya.core.formats.ConfigurationFormat;
>>>>  +import org.apache.tamaya.core.resources.Resource;
>>>>  +import org.apache.tamaya.core.resources.ResourceLoader;
>>>>  +import org.apache.tamaya.spi.PropertySource;
>>>>  +import org.apache.tamaya.spi.PropertySourceProvider;
>>>>  +import org.apache.tamaya.spi.ServiceContext;
>>>>  +
>>>>  +import java.util.ArrayList;
>>>>  +import java.util.Arrays;
>>>>  +import java.util.Collection;
>>>>  +import java.util.List;
>>>>  +import java.util.Objects;
>>>>  +import java.util.logging.Level;
>>>>  +import java.util.logging.Logger;
>>>>  +
>>>>  +/**
>>>>  + * Implementation of a {@link PropertySourceProvider} that reads
>>>>  configuration from some given resource paths
>>>>  + * and using the given formats. The resource path are resolved using the
>>>>  current
>>>>  + * {@link org.apache.tamaya.core.resources.ResourceLoader} active.
>>>>  + */
>>>>  +public class PathBasedPropertySourceProvider implements
>>> PropertySourceProvider
>>>>  {
>>>>  +    /** The logger used. */
>>>>  +    private static final Logger LOG =
>>>>  Logger.getLogger(PathBasedPropertySourceProvider.class.getName());
>>>>  +    /** The property source base name, will be used for creating a useful
>>> name
>>>>  of the
>>>>  +     * {@link org.apache.tamaya.spi.PropertySource} created. */
>>>>  +    private String sourceName;
>>>>  +    /** The config formats supported for the given location/resource
>>> paths. */
>>>>  +    private List<ConfigurationFormat> configFormats = new
>>>>  ArrayList<>();
>>>>  +    /** The paths to be evaluated. */
>>>>  +    private List<String> paths = new ArrayList<>();
>>>>  +
>>>>  +    /**
>>>>  +     * Creates a new instance.
>>>>  +     * @param sourceName the base name of the configuration, used for
>>> creating
>>>>  PropertySource child names.
>>>>  +     * @param formats the formats to be used, not null, not empty.
>>>>  +     * @param paths the paths to be resolved, not null, not empty.
>>>>  +     */
>>>>  +    public PathBasedPropertySourceProvider(String sourceName,
>>>>  List<ConfigurationFormat> formats, String... paths) {
>>>>  +        this.sourceName = Objects.requireNonNull(sourceName);
>>>>  +        this.configFormats.addAll(Objects.requireNonNull(formats));
>>>>  +        this.paths.addAll(Arrays.asList(Objects.requireNonNull(paths)));
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * Creates a new instance.
>>>>  +     * @param sourceName the base name of the configuration, used for
>>> creating
>>>>  PropertySource child names.
>>>>  +     * @param format the format to be used.
>>>>  +     * @param paths the paths to be resolved, not null, not empty.
>>>>  +     */
>>>>  +    public PathBasedPropertySourceProvider(String sourceName,
>>>>  ConfigurationFormat format, String... paths) {
>>>>  +        this.sourceName = Objects.requireNonNull(sourceName);
>>>>  +        this.configFormats.add(Objects.requireNonNull(format));
>>>>  +        this.paths.addAll(Arrays.asList(Objects.requireNonNull(paths)));
>>>>  +    }
>>>>  +
>>>>  +    @Override
>>>>  +    public Collection<PropertySource> getPropertySources() {
>>>>  +        List<PropertySource> propertySources = new
>>> ArrayList<>();
>>>>  +        paths.forEach((path) -> {
>>>>  +            for (Resource res :
>>>>
>>> ServiceContext.getInstance().getService(ResourceLoader.class).get().getResources(path))
>>>
>>>>  {
>>>>  +                try {
>>>>  +                    for (ConfigurationFormat format : configFormats)
>>> {
>>>>  +
>>>>  propertySources.addAll(format.readConfiguration(sourceName, res));
>>>>  +                    }
>>>>  +                } catch (Exception e) {
>>>>  +                    LOG.log(Level.WARNING, "Failed to add resource
>>> based
>>>>  config: " + res.getName(), e);
>>>>  +                }
>>>>  +            }
>>>>  +        });
>>>>  +        return propertySources;
>>>>  +    }
>>>>  +
>>>>  +}
>>>>
>>>>
>>> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
>>>>  ----------------------------------------------------------------------
>>>>  diff --git
>>>>
>>> a/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
>>>>
>>> b/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
>>>>  new file mode 100644
>>>>  index 0000000..de6b578
>>>>  --- /dev/null
>>>>  +++
>>>>
>>> b/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
>>>>  @@ -0,0 +1,102 @@
>>>>  +/*
>>>>  + * Licensed to the Apache Software Foundation (ASF) under one
>>>>  + * or more contributor license agreements.  See the NOTICE file
>>>>  + * distributed with this work for additional information
>>>>  + * regarding copyright ownership.  The ASF licenses this file
>>>>  + * to you under the Apache License, Version 2.0 (the
>>>>  + * "License"); you may not use this file except in compliance
>>>>  + * with the License.  You may obtain a copy of the License at
>>>>  + *
>>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
>>>>  + *
>>>>  + * Unless required by applicable law or agreed to in writing,
>>>>  + * software distributed under the License is distributed on an
>>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>>>  + * KIND, either express or implied.  See the License for the
>>>>  + * specific language governing permissions and limitations
>>>>  + * under the License.
>>>>  + */
>>>>  +package org.apache.tamaya.core;
>>>>  +
>>>>  +import org.apache.tamaya.core.formats.ConfigurationFormat;
>>>>  +import org.apache.tamaya.core.resources.Resource;
>>>>  +import org.apache.tamaya.spi.PropertySource;
>>>>  +import org.apache.tamaya.spi.PropertySourceProvider;
>>>>  +
>>>>  +import java.util.ArrayList;
>>>>  +import java.util.Arrays;
>>>>  +import java.util.Collection;
>>>>  +import java.util.List;
>>>>  +import java.util.Objects;
>>>>  +import java.util.logging.Logger;
>>>>  +
>>>>  +/**
>>>>  + * Implementation of a {@link
>>>>  org.apache.tamaya.spi.PropertySourceProvider} that is based on a single
>>> resource
>>>>  + * and a number of formats.
>>>>  + */
>>>>  +public class ResourcePropertySourceProvider implements
>>> PropertySourceProvider
>>>>  {
>>>>  +    /** The logger used. */
>>>>  +    private static final Logger LOG =
>>>>  Logger.getLogger(ResourcePropertySourceProvider.class.getName());
>>>>  +    /** The supported formats. */
>>>>  +    private List<ConfigurationFormat> formats = new
>>> ArrayList<>();
>>>>  +    /** The resource. */
>>>>  +    private Resource resource;
>>>>  +    /** The source name used for creating the PropertySource names. */
>>>>  +    private String sourceName;
>>>>  +
>>>>  +    /**
>>>>  +     * Creates a new instance.
>>>>  +     * @param resource the {@link
>>>>  org.apache.tamaya.core.resources.Resource}, not null.
>>>>  +     * @param formats the supported formats, not empty.
>>>>  +     */
>>>>  +    public ResourcePropertySourceProvider(String sourceName, Resource
>>> resource,
>>>>  ConfigurationFormat... formats) {
>>>>  +        this(sourceName, resource, Arrays.asList(formats));
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * Creates a new instance.
>>>>  +     * @param resource the {@link
>>>>  org.apache.tamaya.core.resources.Resource}, not null.
>>>>  +     * @param formats the supported formats, not empty.
>>>>  +     */
>>>>  +    public ResourcePropertySourceProvider(String sourceName, Resource
>>> resource,
>>>>  List<ConfigurationFormat> formats) {
>>>>  +        this.resource = Objects.requireNonNull(resource);
>>>>  +        this.sourceName = Objects.requireNonNull(sourceName);
>>>>  +        if(formats.size()==0){
>>>>  +            throw new IllegalArgumentException("Format
>>> required.");
>>>>  +        }
>>>>  +        this.formats.addAll(formats);
>>>>  +    }
>>>>  +
>>>>  +
>>>>  +    /**
>>>>  +     * Get the underlying resource.
>>>>  +     *
>>>>  +     * @return the underlying resource, never null.
>>>>  +     */
>>>>  +    public Resource getResource() {
>>>>  +        return this.resource;
>>>>  +    }
>>>>  +
>>>>  +
>>>>  +    @Override
>>>>  +    public String toString() {
>>>>  +        return "ResourcePropertySourceProvider{" +
>>>>  +                "resource=" + resource +
>>>>  +                ", formats=+" + formats +
>>>>  +                '}';
>>>>  +    }
>>>>  +
>>>>  +    @Override
>>>>  +    public Collection<PropertySource> getPropertySources() {
>>>>  +        List<PropertySource> propertySources = new
>>> ArrayList<>();
>>>>  +        for (ConfigurationFormat format : formats) {
>>>>  +            try {
>>>>  +
>>> propertySources.addAll(format.readConfiguration(sourceName,
>>>>  resource));
>>>>  +            } catch (Exception e) {
>>>>  +                LOG.info(() -> "Format was not matching: " +
>>>>  format + " for resource: " + resource.getName());
>>>>  +            }
>>>>  +        }
>>>>  +        return propertySources;
>>>>  +    }
>>>>  +
>>>>  +}
>>>>
>>>>
>>> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
>>>>  ----------------------------------------------------------------------
>>>>  diff --git
>>>>
>>> a/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
>>>>
>>> b/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
>>>>  new file mode 100644
>>>>  index 0000000..5d289bb
>>>>  --- /dev/null
>>>>  +++
>>> b/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
>>>>  @@ -0,0 +1,53 @@
>>>>  +/*
>>>>  + * Licensed to the Apache Software Foundation (ASF) under one
>>>>  + * or more contributor license agreements.  See the NOTICE file
>>>>  + * distributed with this work for additional information
>>>>  + * regarding copyright ownership.  The ASF licenses this file
>>>>  + * to you under the Apache License, Version 2.0 (the
>>>>  + * "License"); you may not use this file except in compliance
>>>>  + * with the License.  You may obtain a copy of the License at
>>>>  + *
>>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
>>>>  + *
>>>>  + * Unless required by applicable law or agreed to in writing,
>>>>  + * software distributed under the License is distributed on an
>>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>>>  + * KIND, either express or implied.  See the License for the
>>>>  + * specific language governing permissions and limitations
>>>>  + * under the License.
>>>>  + */
>>>>  +package org.apache.tamaya.core.formats;
>>>>  +
>>>>  +import org.apache.tamaya.core.resources.Resource;
>>>>  +import org.apache.tamaya.spi.PropertySource;
>>>>  +
>>>>  +import java.io.IOException;
>>>>  +import java.util.Collection;
>>>>  +
>>>>  +/**
>>>>  + * Implementations current this class encapsulate the mechanism how to
>>> read a
>>>>  + * resource including interpreting the format correctly (e.g. xml vs.
>>>>  + * properties). In most cases file only contains entries of the same
>>> priority,
>>>>  which would then
>>>>  + * result in only one {@link PropertySource}. Complex file formats,
>>>>  hoiwever, may contain entries
>>>>  + * of different priorities. In this cases, each ordinal type found must be
>>>
>>>>  returned as a separate
>>>>  + * {@link PropertySource} instance.
>>>>  + */
>>>>  +@FunctionalInterface
>>>>  +public interface ConfigurationFormat {
>>>>  +
>>>>  +    /**
>>>>  +     * Reads a list {@link org.apache.tamaya.spi.PropertySource}
>>> instances
>>>>  from a resource, using this format.
>>>>  +     * If the configuration format only contains entries of one ordinal
>>> type,
>>>>  normally only one single
>>>>  +     * instance of PropertySource is returned. Nevertheless custom formats
>>> may
>>>>  contain different sections or parts,
>>>>  +     * where each part maps to a different target rdinal (eg defaults,
>>> domain
>>>>  config and app config). In the
>>>>  +     * ladder case multiple PropertySources can be returned, each one with
>>> its
>>>>  own ordinal and the corresponding
>>>>  +     * entries.
>>>>  +     *
>>>>  +     * @param sourceName name to be used for constructing a useful name
>>> for the
>>>>  created
>>>>  +     *                   {@link org.apache.tamaya.spi.PropertySource}
>>>
>>>>  instances.
>>>>  +     * @param resource   the configuration resource, not null
>>>>  +     * @return the corresponding {@link
>>>>  org.apache.tamaya.spi.PropertySource} instances, never {@code null}.
>>>>  +     */
>>>>  +    Collection<PropertySource> readConfiguration(String sourceName,
>>>>  Resource resource) throws IOException;
>>>>  +
>>>>  +}
>>>>
>>>>
>>> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
>>>>  ----------------------------------------------------------------------
>>>>  diff --git
>>>>  a/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
>>>>  b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
>>>>  new file mode 100644
>>>>  index 0000000..3584f8e
>>>>  --- /dev/null
>>>>  +++
>>> b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
>>>>  @@ -0,0 +1,114 @@
>>>>  +/*
>>>>  + * Licensed to the Apache Software Foundation (ASF) under one
>>>>  + * or more contributor license agreements.  See the NOTICE file
>>>>  + * distributed with this work for additional information
>>>>  + * regarding copyright ownership.  The ASF licenses this file
>>>>  + * to you under the Apache License, Version 2.0 (the
>>>>  + * "License"); you may not use this file except in compliance
>>>>  + * with the License.  You may obtain a copy of the License at
>>>>  + *
>>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
>>>>  + *
>>>>  + * Unless required by applicable law or agreed to in writing,
>>>>  + * software distributed under the License is distributed on an
>>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>>>  + * KIND, either express or implied.  See the License for the
>>>>  + * specific language governing permissions and limitations
>>>>  + * under the License.
>>>>  + */
>>>>  +package org.apache.tamaya.core.formats;
>>>>  +
>>>>  +import org.apache.tamaya.core.resources.Resource;
>>>>  +import org.apache.tamaya.spi.PropertySource;
>>>>  +
>>>>  +import java.io.InputStream;
>>>>  +import java.util.ArrayList;
>>>>  +import java.util.Collection;
>>>>  +import java.util.Collections;
>>>>  +import java.util.List;
>>>>  +import java.util.Map;
>>>>  +import java.util.Optional;
>>>>  +import java.util.Properties;
>>>>  +import java.util.logging.Level;
>>>>  +import java.util.logging.Logger;
>>>>  +
>>>>  +/**
>>>>  + * Implementation of a {@link
>>>>  org.apache.tamaya.core.formats.ConfigurationFormat} for -properties files.
>>>>  + *
>>>>  + * @see java.util.Properties#load(java.io.InputStream)
>>>>  + */
>>>>  +public class PropertiesFormat implements ConfigurationFormat {
>>>>  +    /**
>>>>  +     * The logger.
>>>>  +     */
>>>>  +    private final static Logger LOG =
>>>>  Logger.getLogger(PropertiesFormat.class.getName());
>>>>  +
>>>>  +    /**
>>>>  +     * The target ordinal.
>>>>  +     */
>>>>  +    private int ordinal;
>>>>  +
>>>>  +    /**
>>>>  +     * Creates a new format instance, hereby producing entries with the
>>> given
>>>>  ordinal, if not overridden by the
>>>>  +     * configuration itself.
>>>>  +     * TODO document and implement override feature
>>>>  +     * @param ordinal the target ordinal.
>>>>  +     */
>>>>  +    public PropertiesFormat(int ordinal) {
>>>>  +        this.ordinal = ordinal;
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * Get the target ordinal, produced by this format.
>>>>  +     *
>>>>  +     * @return the target ordinal
>>>>  +     */
>>>>  +    public int getOrdinal() {
>>>>  +        return ordinal;
>>>>  +    }
>>>>  +
>>>>  +    @SuppressWarnings("unchecked")
>>>>  +    @Override
>>>>  +    public Collection<PropertySource> readConfiguration(String
>>> baseName,
>>>>  Resource resource) {
>>>>  +        final String sourceName =
>>>>  (baseName==null?"Properties:":baseName) + resource.getName();
>>>>  +        if (resource.exists()) {
>>>>  +            List<PropertySource> propertySources = new
>>>>  ArrayList<>();
>>>>  +            try (InputStream is = resource.getInputStream()) {
>>>>  +                final Properties p = new Properties();
>>>>  +                p.load(is);
>>>>  +                propertySources.add(new PropertySource() {
>>>>  +                    @Override
>>>>  +                    public int getOrdinal() {
>>>>  +                        return ordinal;
>>>>  +                    }
>>>>  +
>>>>  +                    @Override
>>>>  +                    public String getName() {
>>>>  +                        return sourceName;
>>>>  +                    }
>>>>  +
>>>>  +                    @Override
>>>>  +                    public Optional<String> get(String key) {
>>>>  +                        return Optional.ofNullable(p.getProperty(key));
>>>>  +                    }
>>>>  +
>>>>  +                    @Override
>>>>  +                    public Map<String, String> getProperties()
>>> {
>>>>  +                        return Map.class.cast(p);
>>>>  +                    }
>>>>  +                });
>>>>  +                return propertySources;
>>>>  +            } catch (Exception e) {
>>>>  +                LOG.log(Level.FINEST, e, () -> "Failed to read
>>> config
>>>>  from resource: " + resource);
>>>>  +            }
>>>>  +        }
>>>>  +        return Collections.emptyList();
>>>>  +    }
>>>>  +
>>>>  +    @Override
>>>>  +    public String toString() {
>>>>  +        return "PropertiesFormat{" +
>>>>  +                "ordinal=" + ordinal +
>>>>  +                '}';
>>>>  +    }
>>>>  +}
>>>>
>>>>
>>> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
>>>>  ----------------------------------------------------------------------
>>>>  diff --git
>>>>
>>> a/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
>>>>
>>> b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
>>>>  new file mode 100644
>>>>  index 0000000..3f77810
>>>>  --- /dev/null
>>>>  +++
>>> b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
>>>>  @@ -0,0 +1,115 @@
>>>>  +/*
>>>>  + * Licensed to the Apache Software Foundation (ASF) under one
>>>>  + * or more contributor license agreements.  See the NOTICE file
>>>>  + * distributed with this work for additional information
>>>>  + * regarding copyright ownership.  The ASF licenses this file
>>>>  + * to you under the Apache License, Version 2.0 (the
>>>>  + * "License"); you may not use this file except in compliance
>>>>  + * with the License.  You may obtain a copy of the License at
>>>>  + *
>>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
>>>>  + *
>>>>  + * Unless required by applicable law or agreed to in writing,
>>>>  + * software distributed under the License is distributed on an
>>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>>>  + * KIND, either express or implied.  See the License for the
>>>>  + * specific language governing permissions and limitations
>>>>  + * under the License.
>>>>  + */
>>>>  +package org.apache.tamaya.core.formats;
>>>>  +
>>>>  +import org.apache.tamaya.core.resources.Resource;
>>>>  +import org.apache.tamaya.spi.PropertySource;
>>>>  +
>>>>  +import java.io.InputStream;
>>>>  +import java.util.ArrayList;
>>>>  +import java.util.Collection;
>>>>  +import java.util.Collections;
>>>>  +import java.util.List;
>>>>  +import java.util.Map;
>>>>  +import java.util.Optional;
>>>>  +import java.util.Properties;
>>>>  +import java.util.logging.Level;
>>>>  +import java.util.logging.Logger;
>>>>  +
>>>>  +/**
>>>>  + * Implementation of a {@link
>>>>  org.apache.tamaya.core.formats.ConfigurationFormat} for xml property
>>>>  + * files.
>>>>  + *
>>>>  + * @see java.util.Properties#loadFromXML(java.io.InputStream)
>>>>  + */
>>>>  +public class PropertiesXmlFormat implements ConfigurationFormat {
>>>>  +    /**
>>>>  +     * The logger.
>>>>  +     */
>>>>  +    private final static Logger LOG =
>>>>  Logger.getLogger(PropertiesXmlFormat.class.getName());
>>>>  +
>>>>  +    /**
>>>>  +     * The target ordinal.
>>>>  +     */
>>>>  +    private int ordinal;
>>>>  +
>>>>  +    /**
>>>>  +     * Creates a new format instance, producing entries for the given
>>> ordinal,
>>>>  if not overridden by a
>>>>  +     * config entry itself.
>>>>  +     * TODO document and implement override feature
>>>>  +     * @param ordinal the target ordinal.
>>>>  +     */
>>>>  +    public PropertiesXmlFormat(int ordinal) {
>>>>  +        this.ordinal = ordinal;
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * Get the target ordinal, produced by this format.
>>>>  +     *
>>>>  +     * @return the target ordinal
>>>>  +     */
>>>>  +    public int getOrdinal() {
>>>>  +        return ordinal;
>>>>  +    }
>>>>  +
>>>>  +    @SuppressWarnings("unchecked")
>>>>  +    @Override
>>>>  +    public Collection<PropertySource> readConfiguration(String
>>> baseName,
>>>>  Resource resource) {
>>>>  +        if (resource.exists()) {
>>>>  +            final String sourceName =
>>>>  (baseName==null?"Properties:":baseName) + resource.getName();
>>>>  +            List<PropertySource> propertySources = new
>>>>  ArrayList<>();
>>>>  +            try (InputStream is = resource.getInputStream()) {
>>>>  +                final Properties p = new Properties();
>>>>  +                p.loadFromXML(is);
>>>>  +                propertySources.add(new PropertySource() {
>>>>  +                    @Override
>>>>  +                    public int getOrdinal() {
>>>>  +                        return ordinal;
>>>>  +                    }
>>>>  +
>>>>  +                    @Override
>>>>  +                    public String getName() {
>>>>  +                        return sourceName;
>>>>  +                    }
>>>>  +
>>>>  +                    @Override
>>>>  +                    public Optional<String> get(String key) {
>>>>  +                        return Optional.ofNullable(p.getProperty(key));
>>>>  +                    }
>>>>  +
>>>>  +                    @Override
>>>>  +                    public Map<String, String> getProperties()
>>> {
>>>>  +                        return Map.class.cast(p);
>>>>  +                    }
>>>>  +                });
>>>>  +                return propertySources;
>>>>  +            } catch (Exception e) {
>>>>  +                LOG.log(Level.FINEST, e, () -> "Failed to read
>>> config
>>>>  from resource: " + resource);
>>>>  +            }
>>>>  +        }
>>>>  +        return Collections.emptyList();
>>>>  +    }
>>>>  +
>>>>  +    @Override
>>>>  +    public String toString() {
>>>>  +        return "PropertiesXmlFormat{" +
>>>>  +                "ordinal=" + ordinal +
>>>>  +                '}';
>>>>  +    }
>>>>  +}
>>>>
>>>>
>>> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
>>>>  ----------------------------------------------------------------------
>>>>  diff --git
>>>>
>>> a/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
>>>>
>>> b/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
>>>>  index 0a39b7d..3769e27 100644
>>>>  ---
>>>>
>>> a/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
>>>>  +++
>>>>
>>> b/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
>>>>  @@ -22,6 +22,7 @@ import org.apache.tamaya.ConfigException;
>>>>  import org.apache.tamaya.Configuration;
>>>>  import org.apache.tamaya.spi.ConfigurationContext;
>>>>  import org.apache.tamaya.spi.PropertyConverter;
>>>>  +import org.apache.tamaya.spi.PropertyFilter;
>>>>  import org.apache.tamaya.spi.PropertySource;
>>>>  import org.apache.tamaya.spi.ServiceContext;
>>>>
>>>>  @@ -33,6 +34,7 @@ import java.util.Map;
>>>>  import java.util.Optional;
>>>>  import java.util.logging.Level;
>>>>  import java.util.logging.Logger;
>>>>  +import java.util.stream.Collectors;
>>>>
>>>>  /**
>>>>    * Implementation of the Configuration API. This class uses the current
>>>>  {@link ConfigurationContext} to evaluate the
>>>>  @@ -56,13 +58,21 @@ public class DefaultConfiguration implements
>>> Configuration
>>>>  {
>>>>       @Override
>>>>       public Optional<String> get(String key) {
>>>>           List<PropertySource> propertySources =
>>>>
>>> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertySources();
>>>>  +        String unfilteredValue = null;
>>>>           for (PropertySource propertySource : propertySources) {
>>>>               Optional<String> value = propertySource.get(key);
>>>>               if (value.isPresent()) {
>>>>  -                return value;
>>>>  +                unfilteredValue = value.get();
>>>>  +                break;
>>>>               }
>>>>           }
>>>>  -        return Optional.empty();
>>>>  +        // Apply filters to values, prevent values filtered to null!
>>>>  +        for(PropertyFilter filter:
>>>>  +
>>>>
>>> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyFilters()){
>>>>  +            unfilteredValue = filter.filterProperty(key, unfilteredValue,
>>>>  +                    (String k) ->
>>> key.equals(k)?null:get(k).orElse(null));
>>>>  +        }
>>>>  +        return Optional.ofNullable(unfilteredValue);
>>>>       }
>>>>
>>>>       @Override
>>>>  @@ -83,7 +93,15 @@ public class DefaultConfiguration implements
>>> Configuration
>>>>  {
>>>>                   LOG.log(Level.SEVERE, "Error adding properties from
>>>>  PropertySource: " + propertySource +", ignoring
>>> PropertySource.",
>>>>  e);
>>>>               }
>>>>           }
>>>>  -        return result;
>>>>  +        // Apply filters to values, prevent values filtered to null!
>>>>  +        for(PropertyFilter filter:
>>>>  +
>>>>
>>> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyFilters()){
>>>>  +            result.replaceAll((k,v) -> filter.filterProperty(k, v,
>>>>  +                    (String k2) ->
>>> k2.equals(k)?null:get(k2).orElse(null)));
>>>>  +        }
>>>>  +        // Remove null values
>>>>  +        return result.entrySet().parallelStream().filter((e) ->
>>>>  e.getValue()!=null).collect(
>>>>  +                Collectors.toMap((e) -> e.getKey(), (e) ->
>>>>  e.getValue()));
>>>>       }
>>>>
>>>>       /**
>>>>  @@ -101,7 +119,8 @@ public class DefaultConfiguration implements
>>> Configuration
>>>>  {
>>>>       public <T> Optional<T> get(String key, Class<T>
>>> type)
>>>>  {
>>>>           Optional<String> value = get(key);
>>>>           if (value.isPresent()) {
>>>>  -            List<PropertyConverter<T>> converters =
>>>>
>>> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyConverters(type);
>>>>  +            List<PropertyConverter<T>> converters =
>>>>  ServiceContext.getInstance().getService(ConfigurationContext.class)
>>>>  +                    .get().getPropertyConverters(type);
>>>>               for (PropertyConverter<T> converter : converters) {
>>>>                   try {
>>>>                       T t = converter.convert(value.get());
>>>>
>>>>
>>> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
>>>>  ----------------------------------------------------------------------
>>>>  diff --git
>>>>
>>> a/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
>>>
>>>>
>>> b/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
>>>>  new file mode 100644
>>>>  index 0000000..21806cd
>>>>  --- /dev/null
>>>>  +++
>>>>
>>> b/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
>>>>  @@ -0,0 +1,178 @@
>>>>  +/*
>>>>  + * Licensed to the Apache Software Foundation (ASF) under one
>>>>  + * or more contributor license agreements.  See the NOTICE file
>>>>  + * distributed with this work for additional information
>>>>  + * regarding copyright ownership.  The ASF licenses this file
>>>>  + * to you under the Apache License, Version 2.0 (the
>>>>  + * "License"); you may not use this file except in compliance
>>>>  + * with the License.  You may obtain a copy of the License at
>>>>  + *
>>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
>>>>  + *
>>>>  + * Unless required by applicable law or agreed to in writing,
>>>>  + * software distributed under the License is distributed on an
>>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>>>  + * KIND, either express or implied.  See the License for the
>>>>  + * specific language governing permissions and limitations
>>>>  + * under the License.
>>>>  + */
>>>>  +package org.apache.tamaya.core.internal.resource;
>>>>  +
>>>>  +import org.apache.tamaya.core.resources.Resource;
>>>>  +
>>>>  +import java.io.IOException;
>>>>  +import java.io.InputStream;
>>>>  +import java.net.URI;
>>>>  +import java.net.URISyntaxException;
>>>>  +import java.net.URL;
>>>>  +import java.util.Objects;
>>>>  +
>>>>  +/**
>>>>  + * Implementation of {@link Resource} to be loaded from the
>>> classpath.
>>>>  + */
>>>>  +public class ClassPathResource implements Resource {
>>>>  +
>>>>  +    private final String path;
>>>>  +
>>>>  +    private ClassLoader classLoader;
>>>>  +
>>>>  +
>>>>  +    /**
>>>>  +     * Create a new resource using the current context class loader.
>>>>  +     *
>>>>  +     * @param path the resource path, not null
>>>>  +     * @see java.lang.ClassLoader#getResourceAsStream(String)
>>>>  +     */
>>>>  +    public ClassPathResource(String path) {
>>>>  +        this(path, (ClassLoader) null);
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * Create a new resource using the given class loader.
>>>>  +     *
>>>>  +     * @param path        the resource path, not null
>>>>  +     * @param classLoader the class loader to load the resource with,
>>>>  +     *                    or {@code null} for the current context
>>> class
>>>>  loader
>>>>  +     * @see ClassLoader#getResourceAsStream(String)
>>>>  +     */
>>>>  +    public ClassPathResource(String path, ClassLoader classLoader) {
>>>>  +        Objects.requireNonNull(path, "Path null");
>>>>  +        if (path.startsWith("/")) {
>>>>  +            path = path.substring(1);
>>>>  +        }
>>>>  +        this.path = path.trim();
>>>>  +        if(classLoader==null){
>>>>  +            classLoader = Thread.currentThread().getContextClassLoader();
>>>>  +        }
>>>>  +        if(classLoader==null){
>>>>  +            classLoader = getClass().getClassLoader();
>>>>  +        }
>>>>  +        this.classLoader = classLoader;
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * @return the path for this resource.
>>>>  +     */
>>>>  +    public final String getPath() {
>>>>  +        return this.path;
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * @return the ClassLoader that this resource will be accessed from.
>>>>  +     */
>>>>  +    public final ClassLoader getClassLoader() {
>>>>  +        return this.classLoader;
>>>>  +    }
>>>>  +
>>>>  +
>>>>  +    /**
>>>>  +     * Checks if the given resource is resolvable from the configured
>>>>  classloader.
>>>>  +     *
>>>>  +     * @see java.lang.ClassLoader#getResource(String)
>>>>  +     */
>>>>  +    @Override
>>>>  +    public boolean exists() {
>>>>  +        return (resolveURL() != null);
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * Resolves a URL for the underlying class path resource.
>>>>  +     *
>>>>  +     * @return the resolved URL, or {@code null}
>>>>  +     */
>>>>  +    protected URL resolveURL() {
>>>>  +        return this.classLoader.getResource(this.path);
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * This implementation opens an InputStream for the given class path
>>>>  resource.
>>>>  +     *
>>>>  +     * @see java.lang.ClassLoader#getResourceAsStream(String)
>>>>  +     * @see java.lang.Class#getResourceAsStream(String)
>>>>  +     */
>>>>  +    @Override
>>>>  +    public InputStream getInputStream() throws IOException {
>>>>  +        InputStream is = this.classLoader.getResourceAsStream(this.path);
>>>>  +        if (is == null) {
>>>>  +            throw new IOException(getName() + " does not
>>> exist");
>>>>  +        }
>>>>  +        return is;
>>>>  +    }
>>>>  +
>>>>  +    @Override
>>>>  +    public URI toURI() throws IOException {
>>>>  +        try {
>>>>  +            return resolveURL().toURI();
>>>>  +        } catch (URISyntaxException e) {
>>>>  +            throw new IOException(e);
>>>>  +        }
>>>>  +    }
>>>>  +
>>>>  +    @Override
>>>>  +    public long lastModified() throws IOException {
>>>>  +        return 0;
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * This implementation returns the name current the file that this
>>> class
>>>>  path
>>>>  +     * resource refers to.
>>>>  +     */
>>>>  +    @Override
>>>>  +    public String getName() {
>>>>  +        return "classpath:"+path;
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * This implementation returns a description that includes the class
>>> path
>>>>  location.
>>>>  +     */
>>>>  +    @Override
>>>>  +    public String toString() {
>>>>  +        return "ClassPathResource[" + path + ']';
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * This implementation compares the underlying class path locations.
>>>>  +     */
>>>>  +    @Override
>>>>  +    public boolean equals(Object obj) {
>>>>  +        if (obj == this) {
>>>>  +            return true;
>>>>  +        }
>>>>  +        if (obj instanceof ClassPathResource) {
>>>>  +            ClassPathResource otherRes = (ClassPathResource) obj;
>>>>  +            return (this.path.equals(otherRes.path) &&
>>>>  +                    Objects.equals(this.classLoader,
>>> otherRes.classLoader));
>>>>  +        }
>>>>  +        return false;
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * This implementation returns the hash code current the underlying
>>>>  +     * class path location.
>>>>  +     */
>>>>  +    @Override
>>>>  +    public int hashCode() {
>>>>  +        return getName().hashCode();
>>>>  +    }
>>>>  +
>>>>  +}
>>>>
>>>>
>>> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
>>>>  ----------------------------------------------------------------------
>>>>  diff --git
>>>>
>>> a/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
>>>
>>>>
>>> b/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
>>>>  new file mode 100644
>>>>  index 0000000..eb56c1d
>>>>  --- /dev/null
>>>>  +++
>>>>
>>> b/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
>>>>  @@ -0,0 +1,93 @@
>>>>  +/*
>>>>  + * Licensed to the Apache Software Foundation (ASF) under one
>>>>  + * or more contributor license agreements.  See the NOTICE file
>>>>  + * distributed with this work for additional information
>>>>  + * regarding copyright ownership.  The ASF licenses this file
>>>>  + * to you under the Apache License, Version 2.0 (the
>>>>  + * "License"); you may not use this file except in compliance
>>>>  + * with the License.  You may obtain a copy of the License at
>>>>  + *
>>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
>>>>  + *
>>>>  + * Unless required by applicable law or agreed to in writing,
>>>>  + * software distributed under the License is distributed on an
>>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>>>  + * KIND, either express or implied.  See the License for the
>>>>  + * specific language governing permissions and limitations
>>>>  + * under the License.
>>>>  + */
>>>>  +package org.apache.tamaya.core.internal.resource;
>>>>  +
>>>>  +import org.apache.tamaya.core.resources.Resource;
>>>>  +import org.apache.tamaya.core.resources.ResourceLoader;
>>>>  +
>>>>  +import javax.annotation.Priority;
>>>>  +import java.io.File;
>>>>  +import java.net.URL;
>>>>  +import java.util.ArrayList;
>>>>  +import java.util.Collection;
>>>>  +import java.util.Enumeration;
>>>>  +import java.util.List;
>>>>  +import java.util.logging.Logger;
>>>>  +
>>>>  +/**
>>>>  + * Simple default implementation of the resource loader, which does only
>>>>  support direct references to files.
>>>>  + */
>>>>  +@Priority(0)
>>>>  +public class DefaultResourceLoader implements ResourceLoader {
>>>>  +
>>>>  +    private static final Logger LOG =
>>>>  Logger.getLogger(DefaultResourceLoader.class.getName());
>>>>  +
>>>>  +    @Override
>>>>  +    public List<Resource> getResources(ClassLoader classLoader,
>>>>  Collection<String> expressions) {
>>>>  +        List<Resource> resources = new ArrayList<>();
>>>>  +        for (String expression : expressions) {
>>>>  +            if (tryClassPath(classLoader, expression, resources) ||
>>>>  tryFile(expression, resources) ||
>>>>  +                    tryURL(expression, resources)) {
>>>>  +                continue;
>>>>  +            }
>>>>  +            LOG.warning("Failed to resolve resource: " +
>>> expression);
>>>>  +        }
>>>>  +        return resources;
>>>>  +    }
>>>>  +
>>>>  +    private boolean tryClassPath(ClassLoader classLoader, String
>>> expression,
>>>>  List<Resource> resources) {
>>>>  +        try {
>>>>  +            Enumeration<URL> urls =
>>> classLoader.getResources(expression);
>>>>  +            while (urls.hasMoreElements()) {
>>>>  +                URL url = urls.nextElement();
>>>>  +                resources.add(new URLResource(url));
>>>>  +            }
>>>>  +            return !resources.isEmpty();
>>>>  +        } catch (Exception e) {
>>>>  +            LOG.finest(() -> "Failed to load resource from CP:
>>> " +
>>>>  expression);
>>>>  +        }
>>>>  +        return false;
>>>>  +    }
>>>>  +
>>>>  +    private boolean tryFile(String expression, List<Resource>
>>> resources)
>>>>  {
>>>>  +        try {
>>>>  +            File file = new File(expression);
>>>>  +            if (file.exists()) {
>>>>  +                resources.add(new FileResource(file));
>>>>  +                return true;
>>>>  +            }
>>>>  +        } catch (Exception e) {
>>>>  +            LOG.finest(() -> "Failed to load resource from file:
>>> "
>>>>  + expression);
>>>>  +        }
>>>>  +        return false;
>>>>  +    }
>>>>  +
>>>>  +    private boolean tryURL(String expression, List<Resource>
>>> resources)
>>>>  {
>>>>  +        try {
>>>>  +            URL url = new URL(expression);
>>>>  +            resources.add(new URLResource(url));
>>>>  +            return true;
>>>>  +        } catch (Exception e) {
>>>>  +            LOG.finest(() -> "Failed to load resource from file:
>>> "
>>>>  + expression);
>>>>  +        }
>>>>  +        return false;
>>>>  +
>>>>  +    }
>>>>  +
>>>>  +}
>>>>
>>>>
>>> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
>>>>  ----------------------------------------------------------------------
>>>>  diff --git
>>>>
>>> a/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
>>>>
>>> b/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
>>>>  new file mode 100644
>>>>  index 0000000..e0096e5
>>>>  --- /dev/null
>>>>  +++
>>>>
>>> b/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
>>>>  @@ -0,0 +1,162 @@
>>>>  +/*
>>>>  + * Licensed to the Apache Software Foundation (ASF) under one
>>>>  + * or more contributor license agreements.  See the NOTICE file
>>>>  + * distributed with this work for additional information
>>>>  + * regarding copyright ownership.  The ASF licenses this file
>>>>  + * to you under the Apache License, Version 2.0 (the
>>>>  + * "License"); you may not use this file except in compliance
>>>>  + * with the License.  You may obtain a copy of the License at
>>>>  + *
>>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
>>>>  + *
>>>>  + * Unless required by applicable law or agreed to in writing,
>>>>  + * software distributed under the License is distributed on an
>>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>>>  + * KIND, either express or implied.  See the License for the
>>>>  + * specific language governing permissions and limitations
>>>>  + * under the License.
>>>>  + */
>>>>  +package org.apache.tamaya.core.internal.resource;
>>>>  +
>>>>  +import org.apache.tamaya.core.resources.Resource;
>>>>  +
>>>>  +import java.io.File;
>>>>  +import java.io.FileInputStream;
>>>>  +import java.io.IOException;
>>>>  +import java.io.InputStream;
>>>>  +import java.net.URI;
>>>>  +import java.util.Objects;
>>>>  +
>>>>  +/**
>>>>  + * Implementation of {@link
>>> org.apache.tamaya.core.resources.Resource} to
>>>>  be loaded from a file.
>>>>  + * @see java.io.File
>>>>  + */
>>>>  +public class FileResource implements Resource {
>>>>  +
>>>>  +    private final File file;
>>>>  +
>>>>  +    /**
>>>>  +     * Creates a new instance.
>>>>  +     *
>>>>  +     * @param file a File, not null.
>>>>  +     */
>>>>  +    public FileResource(File file) {
>>>>  +        this.file = Objects.requireNonNull(file, "File must not be
>>>>  null");
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * Crreates a new instance.
>>>>  +     *
>>>>  +     * @param filePath a file path
>>>>  +     */
>>>>  +    public FileResource(String filePath) {
>>>>  +        Objects.requireNonNull(filePath, "Path must not be
>>> null");
>>>>  +        this.file = new File(filePath);
>>>>  +    }
>>>>  +
>>>>  +
>>>>  +    /**
>>>>  +     * Get the file path for this resource.
>>>>  +     */
>>>>  +    public final String getPath() {
>>>>  +        return this.file.getPath();
>>>>  +    }
>>>>  +
>>>>  +
>>>>  +    /**
>>>>  +     * This implementation returns whether the underlying file exists.
>>>>  +     *
>>>>  +     * @see java.io.File#exists()
>>>>  +     */
>>>>  +    @Override
>>>>  +    public boolean exists() {
>>>>  +        return this.file.exists();
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * This implementation checks whether the underlying file is marked as
>>>
>>>>  readable
>>>>  +     * (and corresponds to an actual file with content, not to a
>>> directory).
>>>>  +     *
>>>>  +     * @see java.io.File#canRead()
>>>>  +     * @see java.io.File#isDirectory()
>>>>  +     */
>>>>  +    @Override
>>>>  +    public boolean isAccessible() {
>>>>  +        return (this.file.canRead() && !this.file.isDirectory());
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * This implementation opens a FileInputStream for the underlying
>>> file.
>>>>  +     *
>>>>  +     * @see java.io.FileInputStream
>>>>  +     */
>>>>  +    @Override
>>>>  +    public InputStream getInputStream() throws IOException {
>>>>  +        return new FileInputStream(this.file);
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * This implementation returns a URI for the underlying file.
>>>>  +     *
>>>>  +     * @see java.io.File#toURI()
>>>>  +     */
>>>>  +    @Override
>>>>  +    public URI toURI() throws IOException {
>>>>  +        return this.file.toURI();
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * Returns the underlying File's length.
>>>>  +     */
>>>>  +    @Override
>>>>  +    public long length() throws IOException {
>>>>  +        return this.file.length();
>>>>  +    }
>>>>  +
>>>>  +    @Override
>>>>  +    public long lastModified() throws IOException {
>>>>  +        return file.lastModified();
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * Returns the name of the current file.
>>>>  +     *
>>>>  +     * @see java.io.File#getName()
>>>>  +     */
>>>>  +    @Override
>>>>  +    public String getName() {
>>>>  +        return this.file.getName();
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * Returns a description that includes the absolute
>>>>  +     * path of the current file.
>>>>  +     *
>>>>  +     * @see java.io.File#getAbsolutePath()
>>>>  +     */
>>>>  +    @Override
>>>>  +    public String toString() {
>>>>  +        return "File [" + this.file.getAbsolutePath() +
>>>>  "]";
>>>>  +    }
>>>>  +
>>>>  +
>>>>  +    // implementation current WritableResource
>>>>  +
>>>>  +    /**
>>>>  +     * Compares the underlying Files.
>>>>  +     */
>>>>  +    @Override
>>>>  +    public boolean equals(Object obj) {
>>>>  +        return (obj == this ||
>>>>  +                (obj instanceof FileResource &&
>>>>  this.file.equals(((FileResource) obj).file)));
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * Returns hash code current the underlying File reference.
>>>>  +     */
>>>>  +    @Override
>>>>  +    public int hashCode() {
>>>>  +        return this.file.hashCode();
>>>>  +    }
>>>>  +
>>>>  +}
>>>>
>>>>
>>> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
>>>>  ----------------------------------------------------------------------
>>>>  diff --git
>>>>
>>> a/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
>>>
>>>>
>>> b/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
>>>>  new file mode 100644
>>>>  index 0000000..09510b4
>>>>  --- /dev/null
>>>>  +++
>>>>
>>> b/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
>>>>  @@ -0,0 +1,117 @@
>>>>  +/*
>>>>  + * Licensed to the Apache Software Foundation (ASF) under one
>>>>  + * or more contributor license agreements.  See the NOTICE file
>>>>  + * distributed with this work for additional information
>>>>  + * regarding copyright ownership.  The ASF licenses this file
>>>>  + * to you under the Apache License, Version 2.0 (the
>>>>  + * "License"); you may not use this file except in compliance
>>>>  + * with the License.  You may obtain a copy of the License at
>>>>  + *
>>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
>>>>  + *
>>>>  + * Unless required by applicable law or agreed to in writing,
>>>>  + * software distributed under the License is distributed on an
>>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>>>  + * KIND, either express or implied.  See the License for the
>>>>  + * specific language governing permissions and limitations
>>>>  + * under the License.
>>>>  + */
>>>>  +package org.apache.tamaya.core.internal.resource;
>>>>  +
>>>>  +import org.apache.tamaya.core.resources.Resource;
>>>>  +
>>>>  +import java.io.IOException;
>>>>  +import java.io.InputStream;
>>>>  +import java.net.URI;
>>>>  +import java.util.Objects;
>>>>  +
>>>>  +/**
>>>>  + * Simple Resource encapsulating an InputStream.
>>>>  + */
>>>>  +public class InputStreamResource implements Resource {
>>>>  +
>>>>  +    /** The InputStream. */
>>>>  +    private final InputStream inputStream;
>>>>  +    /** The read flag. */
>>>>  +    private boolean read = false;
>>>>  +    /** The name of the resource. */
>>>>  +    private String name;
>>>>  +
>>>>  +
>>>>  +    /**
>>>>  +     * Create a new InputStreamResource.
>>>>  +     *
>>>>  +     * @param inputStream the InputStream to use
>>>>  +     */
>>>>  +    public InputStreamResource(InputStream inputStream) {
>>>>  +        this(inputStream, "InputStream:");
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * Create a new InputStreamResource.
>>>>  +     *
>>>>  +     * @param inputStream the InputStream to use
>>>>  +     * @param name where the InputStream comes from
>>>>  +     */
>>>>  +    public InputStreamResource(InputStream inputStream, String name)
>>> {
>>>>  +        this.inputStream = Objects.requireNonNull(inputStream);
>>>>  +        this.name = (name != null ? name : "InputStream");
>>>>  +    }
>>>>  +
>>>>  +
>>>>  +    /**
>>>>  +     * This implementation always returns {@code true}.
>>>>  +     */
>>>>  +    @Override
>>>>  +    public boolean exists() {
>>>>  +        return true;
>>>>  +    }
>>>>  +
>>>>  +    @Override
>>>>  +    public URI toURI() throws IOException {
>>>>  +        throw new IOException("URI not available.");
>>>>  +    }
>>>>  +
>>>>  +    @Override
>>>>  +    public long lastModified() throws IOException {
>>>>  +        throw new IOException("lastModified not available.");
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * Accesses the input stream. Hereby the input stream can only
>>> accessed
>>>>  once.
>>>>  +     */
>>>>  +    @Override
>>>>  +    public InputStream getInputStream() throws IOException {
>>>>  +        if (this.read) {
>>>>  +            throw new IllegalStateException("InputStream can only be
>>> read
>>>>  once!");
>>>>  +        }
>>>>  +        this.read = true;
>>>>  +        return this.inputStream;
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * This implementation returns the passed-in description, if any.
>>>>  +     */
>>>>  +    public String toString() {
>>>>  +        return this.name != null ? this.name : super.toString();
>>>>  +    }
>>>>  +
>>>>  +
>>>>  +    /**
>>>>  +     * Compares the underlying InputStream.
>>>>  +     */
>>>>  +    @Override
>>>>  +    public boolean equals(Object obj) {
>>>>  +        return (obj == this ||
>>>>  +                (obj instanceof InputStreamResource &&
>>>>  ((InputStreamResource) obj).inputStream.equals(this.inputStream)));
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * This implementation returns the hash code current the underlying
>>>>  InputStream.
>>>>  +     */
>>>>  +    @Override
>>>>  +    public int hashCode() {
>>>>  +        return this.inputStream.hashCode();
>>>>  +    }
>>>>  +
>>>>  +}
>>>>
>>>>
>>> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
>>>>  ----------------------------------------------------------------------
>>>>  diff --git
>>>>
>>> a/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
>>>>
>>> b/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
>>>>  new file mode 100644
>>>>  index 0000000..4da6c53
>>>>  --- /dev/null
>>>>  +++
>>>>
>>> b/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
>>>>  @@ -0,0 +1,37 @@
>>>>  +/*
>>>>  + * Licensed to the Apache Software Foundation (ASF) under one
>>>>  + * or more contributor license agreements.  See the NOTICE file
>>>>  + * distributed with this work for additional information
>>>>  + * regarding copyright ownership.  The ASF licenses this file
>>>>  + * to you under the Apache License, Version 2.0 (the
>>>>  + * "License"); you may not use this file except in compliance
>>>>  + * with the License.  You may obtain a copy of the License at
>>>>  + *
>>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
>>>>  + *
>>>>  + * Unless required by applicable law or agreed to in writing,
>>>>  + * software distributed under the License is distributed on an
>>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>>>  + * KIND, either express or implied.  See the License for the
>>>>  + * specific language governing permissions and limitations
>>>>  + * under the License.
>>>>  + */
>>>>  +package org.apache.tamaya.core.resources;
>>>>  +
>>>>  +import java.io.IOException;
>>>>  +import java.io.InputStream;
>>>>  +
>>>>  +/**
>>>>  + * Simple interface for a component that provides data based on an
>>> InputStream.
>>>>  + */
>>>>  +@FunctionalInterface
>>>>  +public interface InputStreamSupplier {
>>>>  +
>>>>  +    /**
>>>>  +     * Access the input stream.
>>>>  +     * @return the input stream for use.
>>>>  +     * @throws IOException i the input stream could not be obtained.
>>>>  +     */
>>>>  +    InputStream getInputStream() throws IOException;
>>>>  +
>>>>  +}
>>>>
>>>>
>>> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
>>>>  ----------------------------------------------------------------------
>>>>  diff --git
>>> a/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
>>>>  b/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
>>>>  new file mode 100644
>>>>  index 0000000..31c679d
>>>>  --- /dev/null
>>>>  +++ b/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
>>>>  @@ -0,0 +1,115 @@
>>>>  +/*
>>>>  + * Licensed to the Apache Software Foundation (ASF) under one
>>>>  + * or more contributor license agreements.  See the NOTICE file
>>>>  + * distributed with this work for additional information
>>>>  + * regarding copyright ownership.  The ASF licenses this file
>>>>  + * to you under the Apache License, Version 2.0 (the
>>>>  + * "License"); you may not use this file except in compliance
>>>>  + * with the License.  You may obtain a copy of the License at
>>>>  + *
>>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
>>>>  + *
>>>>  + * Unless required by applicable law or agreed to in writing,
>>>>  + * software distributed under the License is distributed on an
>>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>>>  + * KIND, either express or implied.  See the License for the
>>>>  + * specific language governing permissions and limitations
>>>>  + * under the License.
>>>>  + */
>>>>  +package org.apache.tamaya.core.resources;
>>>>  +
>>>>  +import java.io.File;
>>>>  +import java.io.IOException;
>>>>  +import java.io.InputStream;
>>>>  +import java.net.URI;
>>>>  +import java.net.URL;
>>>>  +import java.util.Objects;
>>>>  +
>>>>  +/**
>>>>  + * Interface for an abstract resource. The effective resource
>>> implementation
>>>>  can be completely arbitrary.
>>>>  + * By default files, classpath resources and URLs are supported, but
>>> alternate
>>>>  implementations are possible.
>>>>  + *
>>>>  + * @see #getInputStream()
>>>>  + * @see #toURI()
>>>>  + */
>>>>  +public interface Resource extends InputStreamSupplier {
>>>>  +
>>>>  +    /**
>>>>  +     * Return whether this resource actually exists. Depending on the
>>> resource
>>>>  this can delegate to
>>>>  +     * {@link java.io.File#exists()} or whatever may be appropriate
>>> to
>>>>  check accessibility of the resource.
>>>>  +     */
>>>>  +    default boolean exists() {
>>>>  +        // Try to open a file first, if that fails try to open the
>>> stream...
>>>>  +        try {
>>>>  +            return new File(toURI()).exists();
>>>>  +        } catch (IOException ex) {
>>>>  +            // Fallback
>>>>  +            try {
>>>>  +                InputStream is = getInputStream();
>>>>  +                is.close();
>>>>  +                return true;
>>>>  +            } catch (Exception e) {
>>>>  +                // ignore, just return false for non existing
>>>>  +                return false;
>>>>  +            }
>>>>  +        }
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * Checks whether the resource is accessible, meaning {@link
>>>>  #getInputStream()} should return a InputStream for reading the
>>>>  +     * resource's content.
>>>>  +     *
>>>>  +     * @see #getInputStream()
>>>>  +     */
>>>>  +    default boolean isAccessible() {
>>>>  +        return true;
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * Returns the resource as an URI.
>>>>  +     *
>>>>  +     * @throws IOException if the resource cannot be resolved as URI.
>>>>  +     */
>>>>  +    URI toURI() throws IOException;
>>>>  +
>>>>  +    /**
>>>>  +     * Determines the length for this resource.
>>>>  +     *
>>>>  +     * @throws IOException if the resource is not readable.
>>>>  +     */
>>>>  +    default long length() throws IOException {
>>>>  +        try(InputStream is = this.getInputStream();) {
>>>>  +            Objects.requireNonNull(is, "resource not
>>> available");
>>>>  +            long length = 0;
>>>>  +            byte[] buf = new byte[256];
>>>>  +            int bytesRead;
>>>>  +            while ((bytesRead = is.read(buf)) > 0) {
>>>>  +                length += bytesRead;
>>>>  +            }
>>>>  +            return length;
>>>>  +        }
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * Determine the last-modified timestamp for a resource, as UTC ms
>>>>  timestamp
>>>>  +     *
>>>>  +     * @throws IOException if the resource is not accessible.
>>>>  +     */
>>>>  +    default long lastModified() throws IOException{
>>>>  +        return new File(toURI()).lastModified();
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * Get a name for the resource. The name should be identifying the
>>> resource
>>>>  and also
>>>>  +     * never change, so it must be eligible for hashcode/equals
>>>>  implementations.
>>>>  +     */
>>>>  +    default String getName() {
>>>>  +        try {
>>>>  +            return toURI().toString();
>>>>  +        } catch (Exception e) {
>>>>  +            return toString();
>>>>  +        }
>>>>  +    }
>>>>  +
>>>>  +
>>>>  +}
>>>>  \ No newline at end of file
>>>>
>>>>
>>> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
>>>>  ----------------------------------------------------------------------
>>>>  diff --git
>>>>  a/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
>>>>  b/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
>>>>  new file mode 100644
>>>>  index 0000000..5aff10a
>>>>  --- /dev/null
>>>>  +++
>>> b/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
>>>>  @@ -0,0 +1,91 @@
>>>>  +/*
>>>>  + * Licensed to the Apache Software Foundation (ASF) under one
>>>>  + * or more contributor license agreements.  See the NOTICE file
>>>>  + * distributed with this work for additional information
>>>>  + * regarding copyright ownership.  The ASF licenses this file
>>>>  + * to you under the Apache License, Version 2.0 (the
>>>>  + * "License"); you may not use this file except in compliance
>>>>  + * with the License.  You may obtain a copy of the License at
>>>>  + *
>>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
>>>>  + *
>>>>  + * Unless required by applicable law or agreed to in writing,
>>>>  + * software distributed under the License is distributed on an
>>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>>>  + * KIND, either express or implied.  See the License for the
>>>>  + * specific language governing permissions and limitations
>>>>  + * under the License.
>>>>  + */
>>>>  +package org.apache.tamaya.core.resources;
>>>>  +
>>>>  +import java.util.Arrays;
>>>>  +import java.util.Collection;
>>>>  +import java.util.List;
>>>>  +
>>>>  +/**
>>>>  + * Interface to be implemented by modules. By default only direct
>>> file/resource
>>>>  resolution is supported, whereas
>>>>  + * extension modules may add functionality to perform ant styled pattern
>>>>  resolution of resources.
>>>>  + */
>>>>  +public interface ResourceLoader {
>>>>  +
>>>>  +    /**
>>>>  +     * Resolves resource expressions to a list of {@link
>>>>  org.apache.tamaya.core.resources.Resource}s. Hereby
>>>>  +     * the ordering of resources matches the input of the resolved
>>> expressions.
>>>>  Nevertheless be aware that
>>>>  +     * there is no determined ordering of resources located within a
>>>>  classloader.
>>>>  +     *
>>>>  +     * @param expressions the expressions to be resolved, not empty.
>>>>  +     * @return the corresponding collection of current {@link
>>>>  org.apache.tamaya.core.resources.Resource}s found, never
>>>>  +     * null.
>>>>  +     * .
>>>>  +     */
>>>>  +    default Collection<Resource>
>>> getResources(Collection<String>
>>>>  expressions) {
>>>>  +        ClassLoader cl = Thread.currentThread().getContextClassLoader();
>>>>  +        if (cl == null) {
>>>>  +            cl = getClass().getClassLoader();
>>>>  +        }
>>>>  +        return getResources(cl, expressions);
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * Resolves resource expressions to a list of {@link
>>>>  org.apache.tamaya.core.resources.Resource}s. Hereby
>>>>  +     * the ordering of resources matches the input of the resolved
>>> expressions.
>>>>  Nevertheless be aware that
>>>>  +     * there is no determined ordering of resources located within a
>>>>  classloader.
>>>>  +     *
>>>>  +     * @param expressions the expressions to be resolved, not empty.
>>>>  +     * @return the corresponding collection of current {@link
>>>>  org.apache.tamaya.core.resources.Resource}s found, never
>>>>  +     * null.
>>>>  +     * .
>>>>  +     */
>>>>  +    default Collection<Resource> getResources(String... expressions)
>>>
>>>>  {
>>>>  +        return getResources(Arrays.asList(expressions));
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * Resolves resource expressions to a list of {@link
>>>>  org.apache.tamaya.core.resources.Resource}s, considerubg
>>>>  +     * the given classloader for classloader dependent resources. Hereby
>>>>  +     * the ordering of resources matches the input of the resolved
>>> expressions.
>>>>  Nevertheless be aware that
>>>>  +     * there is no determined ordering of resources located within a
>>>>  classloader.
>>>>  +     *
>>>>  +     * @param expressions the expressions to be resolved, not empty.
>>>>  +     * @return the corresponding collection of current {@link
>>>>  org.apache.tamaya.core.resources.Resource}s found, never
>>>>  +     * null.
>>>>  +     * .
>>>>  +     */
>>>>  +    default Collection<Resource> getResources(ClassLoader
>>> classLoader,
>>>>  String... expressions){
>>>>  +        return getResources(classLoader, Arrays.asList(expressions));
>>>>  +    }
>>>>  +
>>>>  +    /**
>>>>  +     * Resolves resource expressions to a list of {@link
>>>>  org.apache.tamaya.core.resources.Resource}s, considerubg
>>>>  +     * the given classloader for classloader dependent resources. Hereby
>>>>  +     * the ordering of resources matches the input of the resolved
>>> expressions.
>>>>  Nevertheless be aware that
>>>>  +     * there is no determined ordering of resources located within a
>>>>  classloader.
>>>>  +     *
>>>>  +     * @param expressions the expressions to be resolved, not empty.
>>>>  +     * @return the corresponding collection of current {@link
>>>>  org.apache.tamaya.core.resources.Resource}s found, never
>>>>  +     * null.
>>>>  +     * .
>>>>  +     */
>>>>  +    Collection<Resource> getResources(ClassLoader classLoader,
>>>>  Collection<String> expressions);
>>>>  +
>>>>  +}
>>>>
>>>>
>>> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
>>>>  ----------------------------------------------------------------------
>>>>  diff --git
>>> a/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
>>>>  b/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
>>>>  index be1eadb..9c7b894 100644
>>>>  --- a/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
>>>>  +++ b/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
>>>>  @@ -41,6 +41,12 @@ public class ConfigurationTest {
>>>>           assertEquals("Lukas",
>>>>  Configuration.current().get("name3").get());  // oderridden
>>> default
>>>>           assertEquals("Sereina",
>>>>  Configuration.current().get("name4").get()); // final only
>>>>           assertEquals("Benjamin",
>>>>  Configuration.current().get("name5").get()); // final only
>>>>  +
>>>>  +        System.out.println("name : " +
>>>>  Configuration.current().get("name").get());
>>>>  +        System.out.println("name2: " +
>>>>  Configuration.current().get("name2").get());
>>>>  +        System.out.println("name3: " +
>>>>  Configuration.current().get("name3").get());
>>>>  +        System.out.println("name4: " +
>>>>  Configuration.current().get("name4").get());
>>>>  +        System.out.println("name5: " +
>>>>  Configuration.current().get("name5").get());
>>>>       }
>>>>
>>>>
>>>>
>>>>
>>> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
>>>>  ----------------------------------------------------------------------
>>>>  diff --git
>>>>
>>> a/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
>>>
>>>>
>>> b/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
>>>>  deleted file mode 100644
>>>>  index 51cc2dc..0000000
>>>>  ---
>>>>
>>> a/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
>>>>  +++ /dev/null
>>>>  @@ -1,70 +0,0 @@
>>>>  -/*
>>>>  - * Licensed to the Apache Software Foundation (ASF) under one
>>>>  - * or more contributor license agreements.  See the NOTICE file
>>>>  - * distributed with this work for additional information
>>>>  - * regarding copyright ownership.  The ASF licenses this file
>>>>  - * to you under the Apache License, Version 2.0 (the
>>>>  - * "License"); you may not use this file except in compliance
>>>>  - * with the License.  You may obtain a copy of the License at
>>>>  - *
>>>>  - * http://www.apache.org/licenses/LICENSE-2.0
>>>>  - *
>>>>  - * Unless required by applicable law or agreed to in writing,
>>>>  - * software distributed under the License is distributed on an
>>>>  - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>>>  - * KIND, either express or implied.  See the License for the
>>>>  - * specific language governing permissions and limitations
>>>>  - * under the License.
>>>>  - */
>>>>  -package org.apache.tamaya.core.test.propertysource;
>>>>  -
>>>>  -import org.apache.tamaya.core.propertysource.DefaultOrdinal;
>>>>  -import org.apache.tamaya.core.propertysource.EnvironmentPropertySource;
>>>>  -import org.junit.Assert;
>>>>  -import org.junit.Test;
>>>>  -
>>>>  -import java.util.Map;
>>>>  -import java.util.Optional;
>>>>  -
>>>>  -public class EnvironmentPropertySourceTest {
>>>>  -
>>>>  -    private EnvironmentPropertySource propertySource = new
>>>>  EnvironmentPropertySource();
>>>>  -
>>>>  -
>>>>  -    @Test
>>>>  -    public void testGetOrdinal() {
>>>>  -        Assert.assertEquals(DefaultOrdinal.ENVIRONMENT_PROPERTIES,
>>>>  propertySource.getOrdinal());
>>>>  -    }
>>>>  -
>>>>  -    @Test
>>>>  -    public void testGet() {
>>>>  -        String environmentPropertyToCheck =
>>>>  System.getenv().keySet().iterator().next();
>>>>  -
>>>>  -        Optional<String> value =
>>>>  propertySource.get(environmentPropertyToCheck);
>>>>  -        Assert.assertTrue(value.isPresent());
>>>>  -        Assert.assertEquals(System.getenv(environmentPropertyToCheck),
>>>>  value.get());
>>>>  -    }
>>>>  -
>>>>  -    @Test
>>>>  -    public void testGetProperties() {
>>>>  -        Map<String, String> environmentProperties = System.getenv();
>>>>  -
>>>>  -        Assert.assertEquals(environmentProperties.size(),
>>>>  propertySource.getProperties().size());
>>>>  -
>>>>  -        for (Map.Entry<String, String> propertySourceEntry :
>>>>  propertySource.getProperties().entrySet()) {
>>>>  -            Assert.assertEquals("Entry values for key '" +
>>>>  propertySourceEntry.getKey() + "' do not match",
>>>>  -
>>>>  environmentProperties.get(propertySourceEntry.getKey()),
>>>>  propertySourceEntry.getValue());
>>>>  -        }
>>>>  -
>>>>  -        // modification is not allowed
>>>>  -        try {
>>>>  -            propertySource.getProperties().put("add.new.keys",
>>>>  "must throw exception");
>>>>  -            Assert.fail(UnsupportedOperationException.class.getName() +
>>> "
>>>>  expected");
>>>>  -        }
>>>>  -        catch (UnsupportedOperationException e) {
>>>>  -            // expected -> all is fine
>>>>  -        }
>>>>  -    }
>>>>  -
>>>>  -
>>>>  -}
>>>>
>>>>
>>> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
>>>>  ----------------------------------------------------------------------
>>>>  diff --git
>>>>
>>> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
>>>
>>>>
>>> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
>>>>  new file mode 100644
>>>>  index 0000000..5fa90b1
>>>>  --- /dev/null
>>>>  +++
>>>>
>>> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
>>>>  @@ -0,0 +1,32 @@
>>>>  +/*
>>>>  + * Licensed to the Apache Software Foundation (ASF) under one
>>>>  + * or more contributor license agreements.  See the NOTICE file
>>>>  + * distributed with this work for additional information
>>>>  + * regarding copyright ownership.  The ASF licenses this file
>>>>  + * to you under the Apache License, Version 2.0 (the
>>>>  + * "License"); you may not use this file except in compliance
>>>>  + * with the License.  You may obtain a copy of the License at
>>>>  + *
>>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
>>>>  + *
>>>>  + * Unless required by applicable law or agreed to in writing,
>>>>  + * software distributed under the License is distributed on an
>>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>>>  + * KIND, either express or implied.  See the License for the
>>>>  + * specific language governing permissions and limitations
>>>>  + * under the License.
>>>>  + */
>>>>  +package org.apache.tamaya.core.testdata;
>>>>  +
>>>>  +import org.apache.tamaya.core.PathBasedPropertySourceProvider;
>>>>  +import org.apache.tamaya.core.formats.PropertiesFormat;
>>>>  +
>>>>  +/**
>>>>  + * Test provider reading properties from
>>> classpath:cfg/defaults/**.properties.
>>>>  + */
>>>>  +public class TestPropertyDefaultSourceProvider extends
>>>>  PathBasedPropertySourceProvider{
>>>>  +
>>>>  +    public TestPropertyDefaultSourceProvider() {
>>>>  +        super("default-testdata-properties", new
>>>>  PropertiesFormat(100), "classpath:cfg/defaults/**/*.properties");
>>>>  +    }
>>>>  +}
>>>>
>>>>
>>> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
>>>>  ----------------------------------------------------------------------
>>>>  diff --git
>>>>
>>> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
>>>>
>>> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
>>>>  deleted file mode 100644
>>>>  index d1314aa..0000000
>>>>  ---
>>> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
>>>>  +++ /dev/null
>>>>  @@ -1,55 +0,0 @@
>>>>  -/*
>>>>  - * Licensed to the Apache Software Foundation (ASF) under one
>>>>  - * or more contributor license agreements.  See the NOTICE file
>>>>  - * distributed with this work for additional information
>>>>  - * regarding copyright ownership.  The ASF licenses this file
>>>>  - * to you under the Apache License, Version 2.0 (the
>>>>  - * "License"); you may not use this file except in compliance
>>>>  - * with the License.  You may obtain a copy of the License at
>>>>  - *
>>>>  - *  http://www.apache.org/licenses/LICENSE-2.0
>>>>  - *
>>>>  - * Unless required by applicable law or agreed to in writing,
>>>>  - * software distributed under the License is distributed on an
>>>>  - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>>>  - * KIND, either express or implied.  See the License for the
>>>>  - * specific language governing permissions and limitations
>>>>  - * under the License.
>>>>  - */
>>>>  -package org.apache.tamaya.core.testdata;
>>>>  -
>>>>  -import java.util.HashMap;
>>>>  -import java.util.Map;
>>>>  -
>>>>  -import org.apache.tamaya.core.propertysource.BasePropertySource;
>>>>  -
>>>>  -/**
>>>>  - * Test provider reading properties from
>>> classpath:cfg/final/**.properties.
>>>>  - */
>>>>  -public class TestPropertySource extends BasePropertySource {
>>>>  -
>>>>  -    private static final Map<String, String> VALUES;
>>>>  -    static {
>>>>  -        VALUES = new HashMap<String, String>();
>>>>  -        VALUES.put("name", "Robin");
>>>>  -        VALUES.put("name2", "Sabine");
>>>>  -        VALUES.put("name3", "Lukas");
>>>>  -        VALUES.put("name4", "Sereina");
>>>>  -        VALUES.put("name5", "Benjamin");
>>>>  -    }
>>>>  -
>>>>  -
>>>>  -    public TestPropertySource() {
>>>>  -        initialzeOrdinal(100);
>>>>  -    }
>>>>  -
>>>>  -    @Override
>>>>  -    public String getName() {
>>>>  -        return "TestPropertySource";
>>>>  -    }
>>>>  -
>>>>  -    @Override
>>>>  -    public Map<String, String> getProperties() {
>>>>  -        return VALUES;
>>>>  -    }
>>>>  -}
>>>>
>>>>
>>> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
>>>>  ----------------------------------------------------------------------
>>>>  diff --git
>>>>
>>> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
>>>
>>>>
>>> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
>>>>  new file mode 100644
>>>>  index 0000000..beafbf9
>>>>  --- /dev/null
>>>>  +++
>>>>
>>> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
>>>>  @@ -0,0 +1,32 @@
>>>>  +/*
>>>>  + * Licensed to the Apache Software Foundation (ASF) under one
>>>>  + * or more contributor license agreements.  See the NOTICE file
>>>>  + * distributed with this work for additional information
>>>>  + * regarding copyright ownership.  The ASF licenses this file
>>>>  + * to you under the Apache License, Version 2.0 (the
>>>>  + * "License"); you may not use this file except in compliance
>>>>  + * with the License.  You may obtain a copy of the License at
>>>>  + *
>>>>  + *  http://www.apache.org/licenses/LICENSE-2.0
>>>>  + *
>>>>  + * Unless required by applicable law or agreed to in writing,
>>>>  + * software distributed under the License is distributed on an
>>>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>>>  + * KIND, either express or implied.  See the License for the
>>>>  + * specific language governing permissions and limitations
>>>>  + * under the License.
>>>>  + */
>>>>  +package org.apache.tamaya.core.testdata;
>>>>  +
>>>>  +import org.apache.tamaya.core.PathBasedPropertySourceProvider;
>>>>  +import org.apache.tamaya.core.formats.PropertiesFormat;
>>>>  +
>>>>  +/**
>>>>  + * Test provider reading properties from
>>> classpath:cfg/final/**.properties.
>>>>  + */
>>>>  +public class TestPropertySourceProvider extends
>>>>  PathBasedPropertySourceProvider{
>>>>  +
>>>>  +    public TestPropertySourceProvider() {
>>>>  +        super("final-testdata-properties", new
>>> PropertiesFormat(200),
>>>>  "classpath:cfg/final/**/*.properties");
>>>>  +    }
>>>>  +}
>>>>
>>>>
>>> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
>>>>  ----------------------------------------------------------------------
>>>>  diff --git
>>>>
>>> a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
>>>
>>>>
>>> b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
>>>>  deleted file mode 100644
>>>>  index e6f7fad..0000000
>>>>  ---
>>>>
>>> a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
>>>>  +++ /dev/null
>>>>  @@ -1,19 +0,0 @@
>>>>  -#
>>>>  -# Licensed to the Apache Software Foundation (ASF) under one
>>>>  -# or more contributor license agreements.  See the NOTICE file
>>>>  -# distributed with this work for additional information
>>>>  -# regarding copyright ownership.  The ASF licenses this file
>>>>  -# to you under the Apache License, Version 2.0 (the
>>>>  -# "License"); you may not use this file except in compliance
>>>>  -# with the License.  You may obtain a copy current the License at
>>>>  -#
>>>>  -#    http://www.apache.org/licenses/LICENSE-2.0
>>>>  -#
>>>>  -# Unless required by applicable law or agreed to in writing,
>>>>  -# software distributed under the License is distributed on an
>>>>  -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>>>  -# KIND, either express or implied.  See the License for the
>>>>  -# specific language governing permissions and limitations
>>>>  -# under the License.
>>>>  -#
>>>>  -org.apache.tamaya.core.testdata.TestPropertySource
>>>>  \ No newline at end of file
>>>>
>>>>
>>> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
>>>>  ----------------------------------------------------------------------
>>>>  diff --git
>>>>
>>> a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
>>>
>>>>
>>> b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
>>>>  new file mode 100644
>>>>  index 0000000..9db0ef4
>>>>  --- /dev/null
>>>>  +++
>>>>
>>> b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
>>>>  @@ -0,0 +1,20 @@
>>>>  +#
>>>>  +# Licensed to the Apache Software Foundation (ASF) under one
>>>>  +# or more contributor license agreements.  See the NOTICE file
>>>>  +# distributed with this work for additional information
>>>>  +# regarding copyright ownership.  The ASF licenses this file
>>>>  +# to you under the Apache License, Version 2.0 (the
>>>>  +# "License"); you may not use this file except in compliance
>>>>  +# with the License.  You may obtain a copy current the License at
>>>>  +#
>>>>  +#    http://www.apache.org/licenses/LICENSE-2.0
>>>>  +#
>>>>  +# Unless required by applicable law or agreed to in writing,
>>>>  +# software distributed under the License is distributed on an
>>>>  +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>>>  +# KIND, either express or implied.  See the License for the
>>>>  +# specific language governing permissions and limitations
>>>>  +# under the License.
>>>>  +#
>>>>  +org.apache.tamaya.core.testdata.TestPropertyDefaultSourceProvider
>>>>  +org.apache.tamaya.core.testdata.TestPropertySourceProvider
>>>>  \ No newline at end of file
>>>>
>>>
>>
>
>

Re: [2/4] incubator-tamaya git commit: TAMAYA-42, 43, 44: Readded non Spring related parts. Simplified resource API. Readded other tests.

Posted by Anatole Tresch <at...@gmail.com>.
Hi, see inline...

2015-01-04 10:15 GMT+01:00 Romain Manni-Bucau <rm...@gmail.com>:

> Spring logic is more advanced - and broken IMO. It can read from a
> particular jar depending syntax and where it is read from.
>
​Hi, you have to separate here concepts from Spring impl. I dont want to
have Spring, but I want to have a way to easily define a resource location,
where I can descriptively define a pattern of config sources instead of
defining all explicitly, BECAUSE I SIMPLY DO NOT KNOW THE FILES THAT A
DEVELOPER HAS ADDED and in large application configs CONFIGURATION IS
SPREAD ACROSS MULTIPLE RESOURCES, TEAMS, LOCATIONS etc. Ant styled
expression have been shown very easy and intuitive for that. And I want to
have an abstraction for a resource as an interface, so I can really
abstract from the concrete implementation. URL, URI, File: already 2
different artifacts, maybe you also want to add a JDBC connection, a ftp
connection or even a t3s call. Whatever we need an abstraction of top on
that that allows us to decouple that stuff from the rest.

For me it is a secret why you guys struggle with that idea.​



> It brings me to the first question we should have tackled: what is a
> config? For me it is all values which can be hardcoded and then cant be
> packaged inside the app - otherwise you break the predicate "i dont need to
> update my app for a config update". This means all classloader usages would
> be excluded. If this is accepted you only need to be able to provide an URL
> to an existing source to be able to read it so format is the source if it
> has an URL constructor which makes thing really easier IMO.
>

​NO! Configuration MUST BE A USER CONFIGURABLE MIX of
- classpath resources (on different classloaders), these may have different
priorities as defined by the user. It is not the target of Tamaya to define
what users should do, Tamaya must enable them to do it easily.
- file resources (wherever, and with different priorities, policies)
- probably different config formats, e.g. a company may have their own
legacy formats (and locations) active for years, before moving to a moderns
styled config format solely.​ Additionally a file format can contain
defaults, explicit config, overrides (all with different  priorities, so it
will resolve into multiple PropertySources)-
- any other kind of sources, be it a database, ftp sites, landing zones,
whatever. There is no limit here. These locations can be updateable or
fixed, ...
- different Config levels (global defauls, global config, instance
defaults, ... , app defaults, app config, sass overrides). This is handled
by the priorities and will work so far.

Everybody that tries to make it simpler will fail, simply because companies
will not break everything, because a few guys come and have the hammer for
everything. And Tamaya should provide the basic abstraction to solve this.


 Le 4 janv. 2015 10:09, "Mark Struberg" <st...@yahoo.de> a écrit :
>
> > I just became aware that maybe my VOTE was not clear enough.
> >
> > > 2.) Wouldn't it be easier to write the functionality ourselves
> > > and be able to only implement the pieces we really need?
> > > Currently all we need is ClassLoader.getResources() and be done.
> >
> > My aim was not to implement ALL the functionality originally taken from
> > Spring but really only the things we need.
> > And essentially the following:
> >
> > > Currently all we need is ClassLoader.getResources() and be done.
> >
> >
> > Reading Properties from a resource is essentially a single line of code:
> >
> >
> > java.util.Properties.load(ClassLoader.getResource(fileUrl).openStream());
> >
> > I don't yet get the benefit of the other code. Please explain.
> >
> >
> > LieGrue,
> > strub
> >
> >
> >
> >
> >
> > > On Sunday, 4 January 2015, 9:10, Mark Struberg <st...@yahoo.de>
> > wrote:
> > > > Anatole, WHY do we need all of this?
> > >
> > > It is NOWHERE used!
> > >
> > > Why do we add 21 classes which don't provide anything useful to the
> > project?
> > > There was even a VOTE that we should keep it simple and just do the
> > things we
> > > need.
> > >
> > > I really don't get it. Is our goal to create a lightweight but flexible
> > > configuration system or is our goal to become big and fat?
> > >
> > >
> > > Maybe it makes sense but if so then please explain it to us.
> > >
> > >
> > > 1.) Why do we read in a specific format?
> > >
> > > All the system is handling String/String and only in the last step it
> > *probably*
> > > gets converted into a target Type. I fail to see the benefit. Please
> > explain it
> > > to us.
> > >
> > > 2.) Why do we need all the Resource implementations?
> > >
> > > Java provides Resource handling out of the box. Again: we don't need
> any
> > > scripting. So why add some handling for dynamic scenarios which we do
> > not have?
> > > This is basically a copy of Spring.io. But we simply don't have
> anything
> > > scripted in XML as Spring does. So why should we add it?
> > >
> > >
> > > I'm really tired of seeing code all over the place which is not helpful
> > for
> > > the project. Please don't add things we don't really need.
> > >
> > >
> > > LieGrue,
> > > strub
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >>  On Sunday, 4 January 2015, 2:52, "anatole@apache.org"
> > > <an...@apache.org> wrote:
> > >>  >T AMAYA-42,43,44: Readded non Spring related parts. Simplified
> > resource
> > > API.
> > >>  Readded other tests.
> > >>
> > >>
> > >>  Project:
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo
> > >>  Commit:
> > >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/cc237eb4
> > >>  Tree:
> > http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/cc237eb4
> > >>  Diff:
> > http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/cc237eb4
> > >>
> > >>  Branch: refs/heads/master
> > >>  Commit: cc237eb41b7d0c660261f451f47bbf07b7770c46
> > >>  Parents: 59a9e21
> > >>  Author: anatole <an...@apache.org>
> > >>  Authored: Sun Jan 4 02:17:56 2015 +0100
> > >>  Committer: anatole <an...@apache.org>
> > >>  Committed: Sun Jan 4 02:26:23 2015 +0100
> > >>
> > >>
> ----------------------------------------------------------------------
> > >>  .../org/apache/tamaya/spi/PropertyFilter.java   |  10 +-
> > >>  .../core/PathBasedPropertySourceProvider.java   |  93 ++++++++++
> > >>  .../core/ResourcePropertySourceProvider.java    | 102 +++++++++++
> > >>  .../core/formats/ConfigurationFormat.java       |  53 ++++++
> > >>  .../tamaya/core/formats/PropertiesFormat.java   | 114 ++++++++++++
> > >>  .../core/formats/PropertiesXmlFormat.java       | 115 ++++++++++++
> > >>  .../core/internal/DefaultConfiguration.java     |  27 ++-
> > >>  .../internal/resource/ClassPathResource.java    | 178
> > +++++++++++++++++++
> > >>  .../resource/DefaultResourceLoader.java         |  93 ++++++++++
> > >>  .../core/internal/resource/FileResource.java    | 162
> +++++++++++++++++
> > >>  .../internal/resource/InputStreamResource.java  | 117 ++++++++++++
> > >>  .../core/resources/InputStreamSupplier.java     |  37 ++++
> > >>  .../apache/tamaya/core/resources/Resource.java  | 115 ++++++++++++
> > >>  .../tamaya/core/resources/ResourceLoader.java   |  91 ++++++++++
> > >>  .../apache/tamaya/core/ConfigurationTest.java   |   6 +
> > >>  .../EnvironmentPropertySourceTest.java          |  70 --------
> > >>  .../TestPropertyDefaultSourceProvider.java      |  32 ++++
> > >>  .../core/testdata/TestPropertySource.java       |  55 ------
> > >>  .../testdata/TestPropertySourceProvider.java    |  32 ++++
> > >>  .../org.apache.tamaya.spi.PropertySource        |  19 --
> > >>  ...org.apache.tamaya.spi.PropertySourceProvider |  20 +++
> > >>  21 files changed, 1388 insertions(+), 153 deletions(-)
> > >>
> ----------------------------------------------------------------------
> > >>
> > >>
> > >>
> > >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> > >>
> ----------------------------------------------------------------------
> > >>  diff --git
> > a/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> > >>  b/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> > >>  index 7479008..c8626fc 100644
> > >>  --- a/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> > >>  +++ b/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> > >>  @@ -19,7 +19,7 @@
> > >>  package org.apache.tamaya.spi;
> > >>
> > >>
> > >>  -import java.util.Map;
> > >>  +import java.util.function.Function;
> > >>
> > >>  /**
> > >>    * <p>Interface for filtering the current map of properties during
> > > the
> > >>  evaluation of the chain of PropertySources.
> > >>  @@ -27,7 +27,7 @@ import java.util.Map;
> > >>    * hereby is defined by the corresponding {@code @Priority}
> > >>  annotation.</p>
> > >>    * <p>Filters </p>
> > >>    */
> > >>  -public interface PropertyFilter<T>{
> > >>  +public interface PropertyFilter{
> > >>
> > >>       /**
> > >>        * <p>Maps the current {@code valueToBeFiltered} value to a
> > > new
> > >>  value. The resulting value will be used as the result
> > >>  @@ -44,10 +44,10 @@ public interface PropertyFilter<T>{
> > >>        *
> > >>        * @param key the key accessed, not null.
> > >>        * @param valueToBeFiltered the value to be filtered, not null.
> > >>  -     * @param currentMap the current input property map, not null.
> > Can be
> > > used
> > >>  for resolution of the filtered value
> > >>  -     *                   or as datasource for additional
> > meta-information,
> > > such
> > >>  as categories, sensitivity etc.
> > >>  +     * @param propertyValueProvider accessor for reading additional
> > (eg
> > >>  metadata) properties to perform correct
> > >>  +     *                              filtering, never null.
> > >>        * @return the filtered map, never null.
> > >>        */
> > >>  -    String filterProperty(String key, String valueToBeFiltered,
> > >>  Map<String,String> currentMap);
> > >>  +    String filterProperty(String key, String valueToBeFiltered,
> > >>  Function<String,String> propertyValueProvider);
> > >>
> > >>  }
> > >>
> > >>
> > >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
> > >>
> ----------------------------------------------------------------------
> > >>  diff --git
> > >>
> > >
> >
> a/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
> > >
> > >>
> > >
> >
> b/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
> > >>  new file mode 100644
> > >>  index 0000000..31dbf4b
> > >>  --- /dev/null
> > >>  +++
> > >>
> > >
> >
> b/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
> > >>  @@ -0,0 +1,93 @@
> > >>  +/*
> > >>  + * Licensed to the Apache Software Foundation (ASF) under one
> > >>  + * or more contributor license agreements.  See the NOTICE file
> > >>  + * distributed with this work for additional information
> > >>  + * regarding copyright ownership.  The ASF licenses this file
> > >>  + * to you under the Apache License, Version 2.0 (the
> > >>  + * "License"); you may not use this file except in compliance
> > >>  + * with the License.  You may obtain a copy of the License at
> > >>  + *
> > >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> > >>  + *
> > >>  + * Unless required by applicable law or agreed to in writing,
> > >>  + * software distributed under the License is distributed on an
> > >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>  + * KIND, either express or implied.  See the License for the
> > >>  + * specific language governing permissions and limitations
> > >>  + * under the License.
> > >>  + */
> > >>  +package org.apache.tamaya.core;
> > >>  +
> > >>  +import org.apache.tamaya.core.formats.ConfigurationFormat;
> > >>  +import org.apache.tamaya.core.resources.Resource;
> > >>  +import org.apache.tamaya.core.resources.ResourceLoader;
> > >>  +import org.apache.tamaya.spi.PropertySource;
> > >>  +import org.apache.tamaya.spi.PropertySourceProvider;
> > >>  +import org.apache.tamaya.spi.ServiceContext;
> > >>  +
> > >>  +import java.util.ArrayList;
> > >>  +import java.util.Arrays;
> > >>  +import java.util.Collection;
> > >>  +import java.util.List;
> > >>  +import java.util.Objects;
> > >>  +import java.util.logging.Level;
> > >>  +import java.util.logging.Logger;
> > >>  +
> > >>  +/**
> > >>  + * Implementation of a {@link PropertySourceProvider} that reads
> > >>  configuration from some given resource paths
> > >>  + * and using the given formats. The resource path are resolved using
> > the
> > >>  current
> > >>  + * {@link org.apache.tamaya.core.resources.ResourceLoader} active.
> > >>  + */
> > >>  +public class PathBasedPropertySourceProvider implements
> > > PropertySourceProvider
> > >>  {
> > >>  +    /** The logger used. */
> > >>  +    private static final Logger LOG =
> > >>  Logger.getLogger(PathBasedPropertySourceProvider.class.getName());
> > >>  +    /** The property source base name, will be used for creating a
> > useful
> > > name
> > >>  of the
> > >>  +     * {@link org.apache.tamaya.spi.PropertySource} created. */
> > >>  +    private String sourceName;
> > >>  +    /** The config formats supported for the given location/resource
> > > paths. */
> > >>  +    private List<ConfigurationFormat> configFormats = new
> > >>  ArrayList<>();
> > >>  +    /** The paths to be evaluated. */
> > >>  +    private List<String> paths = new ArrayList<>();
> > >>  +
> > >>  +    /**
> > >>  +     * Creates a new instance.
> > >>  +     * @param sourceName the base name of the configuration, used
> for
> > > creating
> > >>  PropertySource child names.
> > >>  +     * @param formats the formats to be used, not null, not empty.
> > >>  +     * @param paths the paths to be resolved, not null, not empty.
> > >>  +     */
> > >>  +    public PathBasedPropertySourceProvider(String sourceName,
> > >>  List<ConfigurationFormat> formats, String... paths) {
> > >>  +        this.sourceName = Objects.requireNonNull(sourceName);
> > >>  +        this.configFormats.addAll(Objects.requireNonNull(formats));
> > >>  +
> > this.paths.addAll(Arrays.asList(Objects.requireNonNull(paths)));
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * Creates a new instance.
> > >>  +     * @param sourceName the base name of the configuration, used
> for
> > > creating
> > >>  PropertySource child names.
> > >>  +     * @param format the format to be used.
> > >>  +     * @param paths the paths to be resolved, not null, not empty.
> > >>  +     */
> > >>  +    public PathBasedPropertySourceProvider(String sourceName,
> > >>  ConfigurationFormat format, String... paths) {
> > >>  +        this.sourceName = Objects.requireNonNull(sourceName);
> > >>  +        this.configFormats.add(Objects.requireNonNull(format));
> > >>  +
> > this.paths.addAll(Arrays.asList(Objects.requireNonNull(paths)));
> > >>  +    }
> > >>  +
> > >>  +    @Override
> > >>  +    public Collection<PropertySource> getPropertySources() {
> > >>  +        List<PropertySource> propertySources = new
> > > ArrayList<>();
> > >>  +        paths.forEach((path) -> {
> > >>  +            for (Resource res :
> > >>
> > >
> >
> ServiceContext.getInstance().getService(ResourceLoader.class).get().getResources(path))
> > >
> > >>  {
> > >>  +                try {
> > >>  +                    for (ConfigurationFormat format : configFormats)
> > > {
> > >>  +
> > >>  propertySources.addAll(format.readConfiguration(sourceName, res));
> > >>  +                    }
> > >>  +                } catch (Exception e) {
> > >>  +                    LOG.log(Level.WARNING, "Failed to add resource
> > > based
> > >>  config: " + res.getName(), e);
> > >>  +                }
> > >>  +            }
> > >>  +        });
> > >>  +        return propertySources;
> > >>  +    }
> > >>  +
> > >>  +}
> > >>
> > >>
> > >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
> > >>
> ----------------------------------------------------------------------
> > >>  diff --git
> > >>
> > >
> >
> a/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
> > >>
> > >
> >
> b/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
> > >>  new file mode 100644
> > >>  index 0000000..de6b578
> > >>  --- /dev/null
> > >>  +++
> > >>
> > >
> >
> b/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
> > >>  @@ -0,0 +1,102 @@
> > >>  +/*
> > >>  + * Licensed to the Apache Software Foundation (ASF) under one
> > >>  + * or more contributor license agreements.  See the NOTICE file
> > >>  + * distributed with this work for additional information
> > >>  + * regarding copyright ownership.  The ASF licenses this file
> > >>  + * to you under the Apache License, Version 2.0 (the
> > >>  + * "License"); you may not use this file except in compliance
> > >>  + * with the License.  You may obtain a copy of the License at
> > >>  + *
> > >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> > >>  + *
> > >>  + * Unless required by applicable law or agreed to in writing,
> > >>  + * software distributed under the License is distributed on an
> > >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>  + * KIND, either express or implied.  See the License for the
> > >>  + * specific language governing permissions and limitations
> > >>  + * under the License.
> > >>  + */
> > >>  +package org.apache.tamaya.core;
> > >>  +
> > >>  +import org.apache.tamaya.core.formats.ConfigurationFormat;
> > >>  +import org.apache.tamaya.core.resources.Resource;
> > >>  +import org.apache.tamaya.spi.PropertySource;
> > >>  +import org.apache.tamaya.spi.PropertySourceProvider;
> > >>  +
> > >>  +import java.util.ArrayList;
> > >>  +import java.util.Arrays;
> > >>  +import java.util.Collection;
> > >>  +import java.util.List;
> > >>  +import java.util.Objects;
> > >>  +import java.util.logging.Logger;
> > >>  +
> > >>  +/**
> > >>  + * Implementation of a {@link
> > >>  org.apache.tamaya.spi.PropertySourceProvider} that is based on a
> single
> > > resource
> > >>  + * and a number of formats.
> > >>  + */
> > >>  +public class ResourcePropertySourceProvider implements
> > > PropertySourceProvider
> > >>  {
> > >>  +    /** The logger used. */
> > >>  +    private static final Logger LOG =
> > >>  Logger.getLogger(ResourcePropertySourceProvider.class.getName());
> > >>  +    /** The supported formats. */
> > >>  +    private List<ConfigurationFormat> formats = new
> > > ArrayList<>();
> > >>  +    /** The resource. */
> > >>  +    private Resource resource;
> > >>  +    /** The source name used for creating the PropertySource names.
> */
> > >>  +    private String sourceName;
> > >>  +
> > >>  +    /**
> > >>  +     * Creates a new instance.
> > >>  +     * @param resource the {@link
> > >>  org.apache.tamaya.core.resources.Resource}, not null.
> > >>  +     * @param formats the supported formats, not empty.
> > >>  +     */
> > >>  +    public ResourcePropertySourceProvider(String sourceName,
> Resource
> > > resource,
> > >>  ConfigurationFormat... formats) {
> > >>  +        this(sourceName, resource, Arrays.asList(formats));
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * Creates a new instance.
> > >>  +     * @param resource the {@link
> > >>  org.apache.tamaya.core.resources.Resource}, not null.
> > >>  +     * @param formats the supported formats, not empty.
> > >>  +     */
> > >>  +    public ResourcePropertySourceProvider(String sourceName,
> Resource
> > > resource,
> > >>  List<ConfigurationFormat> formats) {
> > >>  +        this.resource = Objects.requireNonNull(resource);
> > >>  +        this.sourceName = Objects.requireNonNull(sourceName);
> > >>  +        if(formats.size()==0){
> > >>  +            throw new IllegalArgumentException("Format
> > > required.");
> > >>  +        }
> > >>  +        this.formats.addAll(formats);
> > >>  +    }
> > >>  +
> > >>  +
> > >>  +    /**
> > >>  +     * Get the underlying resource.
> > >>  +     *
> > >>  +     * @return the underlying resource, never null.
> > >>  +     */
> > >>  +    public Resource getResource() {
> > >>  +        return this.resource;
> > >>  +    }
> > >>  +
> > >>  +
> > >>  +    @Override
> > >>  +    public String toString() {
> > >>  +        return "ResourcePropertySourceProvider{" +
> > >>  +                "resource=" + resource +
> > >>  +                ", formats=+" + formats +
> > >>  +                '}';
> > >>  +    }
> > >>  +
> > >>  +    @Override
> > >>  +    public Collection<PropertySource> getPropertySources() {
> > >>  +        List<PropertySource> propertySources = new
> > > ArrayList<>();
> > >>  +        for (ConfigurationFormat format : formats) {
> > >>  +            try {
> > >>  +
> > > propertySources.addAll(format.readConfiguration(sourceName,
> > >>  resource));
> > >>  +            } catch (Exception e) {
> > >>  +                LOG.info(() -> "Format was not matching: " +
> > >>  format + " for resource: " + resource.getName());
> > >>  +            }
> > >>  +        }
> > >>  +        return propertySources;
> > >>  +    }
> > >>  +
> > >>  +}
> > >>
> > >>
> > >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
> > >>
> ----------------------------------------------------------------------
> > >>  diff --git
> > >>
> > >
> >
> a/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
> > >>
> > >
> >
> b/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
> > >>  new file mode 100644
> > >>  index 0000000..5d289bb
> > >>  --- /dev/null
> > >>  +++
> > >
> >
> b/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
> > >>  @@ -0,0 +1,53 @@
> > >>  +/*
> > >>  + * Licensed to the Apache Software Foundation (ASF) under one
> > >>  + * or more contributor license agreements.  See the NOTICE file
> > >>  + * distributed with this work for additional information
> > >>  + * regarding copyright ownership.  The ASF licenses this file
> > >>  + * to you under the Apache License, Version 2.0 (the
> > >>  + * "License"); you may not use this file except in compliance
> > >>  + * with the License.  You may obtain a copy of the License at
> > >>  + *
> > >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> > >>  + *
> > >>  + * Unless required by applicable law or agreed to in writing,
> > >>  + * software distributed under the License is distributed on an
> > >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>  + * KIND, either express or implied.  See the License for the
> > >>  + * specific language governing permissions and limitations
> > >>  + * under the License.
> > >>  + */
> > >>  +package org.apache.tamaya.core.formats;
> > >>  +
> > >>  +import org.apache.tamaya.core.resources.Resource;
> > >>  +import org.apache.tamaya.spi.PropertySource;
> > >>  +
> > >>  +import java.io.IOException;
> > >>  +import java.util.Collection;
> > >>  +
> > >>  +/**
> > >>  + * Implementations current this class encapsulate the mechanism how
> to
> > > read a
> > >>  + * resource including interpreting the format correctly (e.g. xml
> vs.
> > >>  + * properties). In most cases file only contains entries of the same
> > > priority,
> > >>  which would then
> > >>  + * result in only one {@link PropertySource}. Complex file formats,
> > >>  hoiwever, may contain entries
> > >>  + * of different priorities. In this cases, each ordinal type found
> > must be
> > >
> > >>  returned as a separate
> > >>  + * {@link PropertySource} instance.
> > >>  + */
> > >>  +@FunctionalInterface
> > >>  +public interface ConfigurationFormat {
> > >>  +
> > >>  +    /**
> > >>  +     * Reads a list {@link org.apache.tamaya.spi.PropertySource}
> > > instances
> > >>  from a resource, using this format.
> > >>  +     * If the configuration format only contains entries of one
> > ordinal
> > > type,
> > >>  normally only one single
> > >>  +     * instance of PropertySource is returned. Nevertheless custom
> > formats
> > > may
> > >>  contain different sections or parts,
> > >>  +     * where each part maps to a different target rdinal (eg
> defaults,
> > > domain
> > >>  config and app config). In the
> > >>  +     * ladder case multiple PropertySources can be returned, each
> one
> > with
> > > its
> > >>  own ordinal and the corresponding
> > >>  +     * entries.
> > >>  +     *
> > >>  +     * @param sourceName name to be used for constructing a useful
> > name
> > > for the
> > >>  created
> > >>  +     *                   {@link
> org.apache.tamaya.spi.PropertySource}
> > >
> > >>  instances.
> > >>  +     * @param resource   the configuration resource, not null
> > >>  +     * @return the corresponding {@link
> > >>  org.apache.tamaya.spi.PropertySource} instances, never {@code null}.
> > >>  +     */
> > >>  +    Collection<PropertySource> readConfiguration(String sourceName,
> > >>  Resource resource) throws IOException;
> > >>  +
> > >>  +}
> > >>
> > >>
> > >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
> > >>
> ----------------------------------------------------------------------
> > >>  diff --git
> > >>
> > a/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
> > >>
> > b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
> > >>  new file mode 100644
> > >>  index 0000000..3584f8e
> > >>  --- /dev/null
> > >>  +++
> > >
> b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
> > >>  @@ -0,0 +1,114 @@
> > >>  +/*
> > >>  + * Licensed to the Apache Software Foundation (ASF) under one
> > >>  + * or more contributor license agreements.  See the NOTICE file
> > >>  + * distributed with this work for additional information
> > >>  + * regarding copyright ownership.  The ASF licenses this file
> > >>  + * to you under the Apache License, Version 2.0 (the
> > >>  + * "License"); you may not use this file except in compliance
> > >>  + * with the License.  You may obtain a copy of the License at
> > >>  + *
> > >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> > >>  + *
> > >>  + * Unless required by applicable law or agreed to in writing,
> > >>  + * software distributed under the License is distributed on an
> > >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>  + * KIND, either express or implied.  See the License for the
> > >>  + * specific language governing permissions and limitations
> > >>  + * under the License.
> > >>  + */
> > >>  +package org.apache.tamaya.core.formats;
> > >>  +
> > >>  +import org.apache.tamaya.core.resources.Resource;
> > >>  +import org.apache.tamaya.spi.PropertySource;
> > >>  +
> > >>  +import java.io.InputStream;
> > >>  +import java.util.ArrayList;
> > >>  +import java.util.Collection;
> > >>  +import java.util.Collections;
> > >>  +import java.util.List;
> > >>  +import java.util.Map;
> > >>  +import java.util.Optional;
> > >>  +import java.util.Properties;
> > >>  +import java.util.logging.Level;
> > >>  +import java.util.logging.Logger;
> > >>  +
> > >>  +/**
> > >>  + * Implementation of a {@link
> > >>  org.apache.tamaya.core.formats.ConfigurationFormat} for -properties
> > files.
> > >>  + *
> > >>  + * @see java.util.Properties#load(java.io.InputStream)
> > >>  + */
> > >>  +public class PropertiesFormat implements ConfigurationFormat {
> > >>  +    /**
> > >>  +     * The logger.
> > >>  +     */
> > >>  +    private final static Logger LOG =
> > >>  Logger.getLogger(PropertiesFormat.class.getName());
> > >>  +
> > >>  +    /**
> > >>  +     * The target ordinal.
> > >>  +     */
> > >>  +    private int ordinal;
> > >>  +
> > >>  +    /**
> > >>  +     * Creates a new format instance, hereby producing entries with
> > the
> > > given
> > >>  ordinal, if not overridden by the
> > >>  +     * configuration itself.
> > >>  +     * TODO document and implement override feature
> > >>  +     * @param ordinal the target ordinal.
> > >>  +     */
> > >>  +    public PropertiesFormat(int ordinal) {
> > >>  +        this.ordinal = ordinal;
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * Get the target ordinal, produced by this format.
> > >>  +     *
> > >>  +     * @return the target ordinal
> > >>  +     */
> > >>  +    public int getOrdinal() {
> > >>  +        return ordinal;
> > >>  +    }
> > >>  +
> > >>  +    @SuppressWarnings("unchecked")
> > >>  +    @Override
> > >>  +    public Collection<PropertySource> readConfiguration(String
> > > baseName,
> > >>  Resource resource) {
> > >>  +        final String sourceName =
> > >>  (baseName==null?"Properties:":baseName) + resource.getName();
> > >>  +        if (resource.exists()) {
> > >>  +            List<PropertySource> propertySources = new
> > >>  ArrayList<>();
> > >>  +            try (InputStream is = resource.getInputStream()) {
> > >>  +                final Properties p = new Properties();
> > >>  +                p.load(is);
> > >>  +                propertySources.add(new PropertySource() {
> > >>  +                    @Override
> > >>  +                    public int getOrdinal() {
> > >>  +                        return ordinal;
> > >>  +                    }
> > >>  +
> > >>  +                    @Override
> > >>  +                    public String getName() {
> > >>  +                        return sourceName;
> > >>  +                    }
> > >>  +
> > >>  +                    @Override
> > >>  +                    public Optional<String> get(String key) {
> > >>  +                        return
> > Optional.ofNullable(p.getProperty(key));
> > >>  +                    }
> > >>  +
> > >>  +                    @Override
> > >>  +                    public Map<String, String> getProperties()
> > > {
> > >>  +                        return Map.class.cast(p);
> > >>  +                    }
> > >>  +                });
> > >>  +                return propertySources;
> > >>  +            } catch (Exception e) {
> > >>  +                LOG.log(Level.FINEST, e, () -> "Failed to read
> > > config
> > >>  from resource: " + resource);
> > >>  +            }
> > >>  +        }
> > >>  +        return Collections.emptyList();
> > >>  +    }
> > >>  +
> > >>  +    @Override
> > >>  +    public String toString() {
> > >>  +        return "PropertiesFormat{" +
> > >>  +                "ordinal=" + ordinal +
> > >>  +                '}';
> > >>  +    }
> > >>  +}
> > >>
> > >>
> > >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
> > >>
> ----------------------------------------------------------------------
> > >>  diff --git
> > >>
> > >
> >
> a/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
> > >>
> > >
> >
> b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
> > >>  new file mode 100644
> > >>  index 0000000..3f77810
> > >>  --- /dev/null
> > >>  +++
> > >
> >
> b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
> > >>  @@ -0,0 +1,115 @@
> > >>  +/*
> > >>  + * Licensed to the Apache Software Foundation (ASF) under one
> > >>  + * or more contributor license agreements.  See the NOTICE file
> > >>  + * distributed with this work for additional information
> > >>  + * regarding copyright ownership.  The ASF licenses this file
> > >>  + * to you under the Apache License, Version 2.0 (the
> > >>  + * "License"); you may not use this file except in compliance
> > >>  + * with the License.  You may obtain a copy of the License at
> > >>  + *
> > >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> > >>  + *
> > >>  + * Unless required by applicable law or agreed to in writing,
> > >>  + * software distributed under the License is distributed on an
> > >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>  + * KIND, either express or implied.  See the License for the
> > >>  + * specific language governing permissions and limitations
> > >>  + * under the License.
> > >>  + */
> > >>  +package org.apache.tamaya.core.formats;
> > >>  +
> > >>  +import org.apache.tamaya.core.resources.Resource;
> > >>  +import org.apache.tamaya.spi.PropertySource;
> > >>  +
> > >>  +import java.io.InputStream;
> > >>  +import java.util.ArrayList;
> > >>  +import java.util.Collection;
> > >>  +import java.util.Collections;
> > >>  +import java.util.List;
> > >>  +import java.util.Map;
> > >>  +import java.util.Optional;
> > >>  +import java.util.Properties;
> > >>  +import java.util.logging.Level;
> > >>  +import java.util.logging.Logger;
> > >>  +
> > >>  +/**
> > >>  + * Implementation of a {@link
> > >>  org.apache.tamaya.core.formats.ConfigurationFormat} for xml property
> > >>  + * files.
> > >>  + *
> > >>  + * @see java.util.Properties#loadFromXML(java.io.InputStream)
> > >>  + */
> > >>  +public class PropertiesXmlFormat implements ConfigurationFormat {
> > >>  +    /**
> > >>  +     * The logger.
> > >>  +     */
> > >>  +    private final static Logger LOG =
> > >>  Logger.getLogger(PropertiesXmlFormat.class.getName());
> > >>  +
> > >>  +    /**
> > >>  +     * The target ordinal.
> > >>  +     */
> > >>  +    private int ordinal;
> > >>  +
> > >>  +    /**
> > >>  +     * Creates a new format instance, producing entries for the
> given
> > > ordinal,
> > >>  if not overridden by a
> > >>  +     * config entry itself.
> > >>  +     * TODO document and implement override feature
> > >>  +     * @param ordinal the target ordinal.
> > >>  +     */
> > >>  +    public PropertiesXmlFormat(int ordinal) {
> > >>  +        this.ordinal = ordinal;
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * Get the target ordinal, produced by this format.
> > >>  +     *
> > >>  +     * @return the target ordinal
> > >>  +     */
> > >>  +    public int getOrdinal() {
> > >>  +        return ordinal;
> > >>  +    }
> > >>  +
> > >>  +    @SuppressWarnings("unchecked")
> > >>  +    @Override
> > >>  +    public Collection<PropertySource> readConfiguration(String
> > > baseName,
> > >>  Resource resource) {
> > >>  +        if (resource.exists()) {
> > >>  +            final String sourceName =
> > >>  (baseName==null?"Properties:":baseName) + resource.getName();
> > >>  +            List<PropertySource> propertySources = new
> > >>  ArrayList<>();
> > >>  +            try (InputStream is = resource.getInputStream()) {
> > >>  +                final Properties p = new Properties();
> > >>  +                p.loadFromXML(is);
> > >>  +                propertySources.add(new PropertySource() {
> > >>  +                    @Override
> > >>  +                    public int getOrdinal() {
> > >>  +                        return ordinal;
> > >>  +                    }
> > >>  +
> > >>  +                    @Override
> > >>  +                    public String getName() {
> > >>  +                        return sourceName;
> > >>  +                    }
> > >>  +
> > >>  +                    @Override
> > >>  +                    public Optional<String> get(String key) {
> > >>  +                        return
> > Optional.ofNullable(p.getProperty(key));
> > >>  +                    }
> > >>  +
> > >>  +                    @Override
> > >>  +                    public Map<String, String> getProperties()
> > > {
> > >>  +                        return Map.class.cast(p);
> > >>  +                    }
> > >>  +                });
> > >>  +                return propertySources;
> > >>  +            } catch (Exception e) {
> > >>  +                LOG.log(Level.FINEST, e, () -> "Failed to read
> > > config
> > >>  from resource: " + resource);
> > >>  +            }
> > >>  +        }
> > >>  +        return Collections.emptyList();
> > >>  +    }
> > >>  +
> > >>  +    @Override
> > >>  +    public String toString() {
> > >>  +        return "PropertiesXmlFormat{" +
> > >>  +                "ordinal=" + ordinal +
> > >>  +                '}';
> > >>  +    }
> > >>  +}
> > >>
> > >>
> > >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> > >>
> ----------------------------------------------------------------------
> > >>  diff --git
> > >>
> > >
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> > >>
> > >
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> > >>  index 0a39b7d..3769e27 100644
> > >>  ---
> > >>
> > >
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> > >>  +++
> > >>
> > >
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> > >>  @@ -22,6 +22,7 @@ import org.apache.tamaya.ConfigException;
> > >>  import org.apache.tamaya.Configuration;
> > >>  import org.apache.tamaya.spi.ConfigurationContext;
> > >>  import org.apache.tamaya.spi.PropertyConverter;
> > >>  +import org.apache.tamaya.spi.PropertyFilter;
> > >>  import org.apache.tamaya.spi.PropertySource;
> > >>  import org.apache.tamaya.spi.ServiceContext;
> > >>
> > >>  @@ -33,6 +34,7 @@ import java.util.Map;
> > >>  import java.util.Optional;
> > >>  import java.util.logging.Level;
> > >>  import java.util.logging.Logger;
> > >>  +import java.util.stream.Collectors;
> > >>
> > >>  /**
> > >>    * Implementation of the Configuration API. This class uses the
> > current
> > >>  {@link ConfigurationContext} to evaluate the
> > >>  @@ -56,13 +58,21 @@ public class DefaultConfiguration implements
> > > Configuration
> > >>  {
> > >>       @Override
> > >>       public Optional<String> get(String key) {
> > >>           List<PropertySource> propertySources =
> > >>
> > >
> >
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertySources();
> > >>  +        String unfilteredValue = null;
> > >>           for (PropertySource propertySource : propertySources) {
> > >>               Optional<String> value = propertySource.get(key);
> > >>               if (value.isPresent()) {
> > >>  -                return value;
> > >>  +                unfilteredValue = value.get();
> > >>  +                break;
> > >>               }
> > >>           }
> > >>  -        return Optional.empty();
> > >>  +        // Apply filters to values, prevent values filtered to null!
> > >>  +        for(PropertyFilter filter:
> > >>  +
> > >>
> > >
> >
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyFilters()){
> > >>  +            unfilteredValue = filter.filterProperty(key,
> > unfilteredValue,
> > >>  +                    (String k) ->
> > > key.equals(k)?null:get(k).orElse(null));
> > >>  +        }
> > >>  +        return Optional.ofNullable(unfilteredValue);
> > >>       }
> > >>
> > >>       @Override
> > >>  @@ -83,7 +93,15 @@ public class DefaultConfiguration implements
> > > Configuration
> > >>  {
> > >>                   LOG.log(Level.SEVERE, "Error adding properties from
> > >>  PropertySource: " + propertySource +", ignoring
> > > PropertySource.",
> > >>  e);
> > >>               }
> > >>           }
> > >>  -        return result;
> > >>  +        // Apply filters to values, prevent values filtered to null!
> > >>  +        for(PropertyFilter filter:
> > >>  +
> > >>
> > >
> >
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyFilters()){
> > >>  +            result.replaceAll((k,v) -> filter.filterProperty(k, v,
> > >>  +                    (String k2) ->
> > > k2.equals(k)?null:get(k2).orElse(null)));
> > >>  +        }
> > >>  +        // Remove null values
> > >>  +        return result.entrySet().parallelStream().filter((e) ->
> > >>  e.getValue()!=null).collect(
> > >>  +                Collectors.toMap((e) -> e.getKey(), (e) ->
> > >>  e.getValue()));
> > >>       }
> > >>
> > >>       /**
> > >>  @@ -101,7 +119,8 @@ public class DefaultConfiguration implements
> > > Configuration
> > >>  {
> > >>       public <T> Optional<T> get(String key, Class<T>
> > > type)
> > >>  {
> > >>           Optional<String> value = get(key);
> > >>           if (value.isPresent()) {
> > >>  -            List<PropertyConverter<T>> converters =
> > >>
> > >
> >
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyConverters(type);
> > >>  +            List<PropertyConverter<T>> converters =
> > >>  ServiceContext.getInstance().getService(ConfigurationContext.class)
> > >>  +                    .get().getPropertyConverters(type);
> > >>               for (PropertyConverter<T> converter : converters) {
> > >>                   try {
> > >>                       T t = converter.convert(value.get());
> > >>
> > >>
> > >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
> > >>
> ----------------------------------------------------------------------
> > >>  diff --git
> > >>
> > >
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
> > >
> > >>
> > >
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
> > >>  new file mode 100644
> > >>  index 0000000..21806cd
> > >>  --- /dev/null
> > >>  +++
> > >>
> > >
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
> > >>  @@ -0,0 +1,178 @@
> > >>  +/*
> > >>  + * Licensed to the Apache Software Foundation (ASF) under one
> > >>  + * or more contributor license agreements.  See the NOTICE file
> > >>  + * distributed with this work for additional information
> > >>  + * regarding copyright ownership.  The ASF licenses this file
> > >>  + * to you under the Apache License, Version 2.0 (the
> > >>  + * "License"); you may not use this file except in compliance
> > >>  + * with the License.  You may obtain a copy of the License at
> > >>  + *
> > >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> > >>  + *
> > >>  + * Unless required by applicable law or agreed to in writing,
> > >>  + * software distributed under the License is distributed on an
> > >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>  + * KIND, either express or implied.  See the License for the
> > >>  + * specific language governing permissions and limitations
> > >>  + * under the License.
> > >>  + */
> > >>  +package org.apache.tamaya.core.internal.resource;
> > >>  +
> > >>  +import org.apache.tamaya.core.resources.Resource;
> > >>  +
> > >>  +import java.io.IOException;
> > >>  +import java.io.InputStream;
> > >>  +import java.net.URI;
> > >>  +import java.net.URISyntaxException;
> > >>  +import java.net.URL;
> > >>  +import java.util.Objects;
> > >>  +
> > >>  +/**
> > >>  + * Implementation of {@link Resource} to be loaded from the
> > > classpath.
> > >>  + */
> > >>  +public class ClassPathResource implements Resource {
> > >>  +
> > >>  +    private final String path;
> > >>  +
> > >>  +    private ClassLoader classLoader;
> > >>  +
> > >>  +
> > >>  +    /**
> > >>  +     * Create a new resource using the current context class loader.
> > >>  +     *
> > >>  +     * @param path the resource path, not null
> > >>  +     * @see java.lang.ClassLoader#getResourceAsStream(String)
> > >>  +     */
> > >>  +    public ClassPathResource(String path) {
> > >>  +        this(path, (ClassLoader) null);
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * Create a new resource using the given class loader.
> > >>  +     *
> > >>  +     * @param path        the resource path, not null
> > >>  +     * @param classLoader the class loader to load the resource
> with,
> > >>  +     *                    or {@code null} for the current context
> > > class
> > >>  loader
> > >>  +     * @see ClassLoader#getResourceAsStream(String)
> > >>  +     */
> > >>  +    public ClassPathResource(String path, ClassLoader classLoader) {
> > >>  +        Objects.requireNonNull(path, "Path null");
> > >>  +        if (path.startsWith("/")) {
> > >>  +            path = path.substring(1);
> > >>  +        }
> > >>  +        this.path = path.trim();
> > >>  +        if(classLoader==null){
> > >>  +            classLoader =
> > Thread.currentThread().getContextClassLoader();
> > >>  +        }
> > >>  +        if(classLoader==null){
> > >>  +            classLoader = getClass().getClassLoader();
> > >>  +        }
> > >>  +        this.classLoader = classLoader;
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * @return the path for this resource.
> > >>  +     */
> > >>  +    public final String getPath() {
> > >>  +        return this.path;
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * @return the ClassLoader that this resource will be accessed
> > from.
> > >>  +     */
> > >>  +    public final ClassLoader getClassLoader() {
> > >>  +        return this.classLoader;
> > >>  +    }
> > >>  +
> > >>  +
> > >>  +    /**
> > >>  +     * Checks if the given resource is resolvable from the
> configured
> > >>  classloader.
> > >>  +     *
> > >>  +     * @see java.lang.ClassLoader#getResource(String)
> > >>  +     */
> > >>  +    @Override
> > >>  +    public boolean exists() {
> > >>  +        return (resolveURL() != null);
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * Resolves a URL for the underlying class path resource.
> > >>  +     *
> > >>  +     * @return the resolved URL, or {@code null}
> > >>  +     */
> > >>  +    protected URL resolveURL() {
> > >>  +        return this.classLoader.getResource(this.path);
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * This implementation opens an InputStream for the given class
> > path
> > >>  resource.
> > >>  +     *
> > >>  +     * @see java.lang.ClassLoader#getResourceAsStream(String)
> > >>  +     * @see java.lang.Class#getResourceAsStream(String)
> > >>  +     */
> > >>  +    @Override
> > >>  +    public InputStream getInputStream() throws IOException {
> > >>  +        InputStream is =
> > this.classLoader.getResourceAsStream(this.path);
> > >>  +        if (is == null) {
> > >>  +            throw new IOException(getName() + " does not
> > > exist");
> > >>  +        }
> > >>  +        return is;
> > >>  +    }
> > >>  +
> > >>  +    @Override
> > >>  +    public URI toURI() throws IOException {
> > >>  +        try {
> > >>  +            return resolveURL().toURI();
> > >>  +        } catch (URISyntaxException e) {
> > >>  +            throw new IOException(e);
> > >>  +        }
> > >>  +    }
> > >>  +
> > >>  +    @Override
> > >>  +    public long lastModified() throws IOException {
> > >>  +        return 0;
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * This implementation returns the name current the file that
> this
> > > class
> > >>  path
> > >>  +     * resource refers to.
> > >>  +     */
> > >>  +    @Override
> > >>  +    public String getName() {
> > >>  +        return "classpath:"+path;
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * This implementation returns a description that includes the
> > class
> > > path
> > >>  location.
> > >>  +     */
> > >>  +    @Override
> > >>  +    public String toString() {
> > >>  +        return "ClassPathResource[" + path + ']';
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * This implementation compares the underlying class path
> > locations.
> > >>  +     */
> > >>  +    @Override
> > >>  +    public boolean equals(Object obj) {
> > >>  +        if (obj == this) {
> > >>  +            return true;
> > >>  +        }
> > >>  +        if (obj instanceof ClassPathResource) {
> > >>  +            ClassPathResource otherRes = (ClassPathResource) obj;
> > >>  +            return (this.path.equals(otherRes.path) &&
> > >>  +                    Objects.equals(this.classLoader,
> > > otherRes.classLoader));
> > >>  +        }
> > >>  +        return false;
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * This implementation returns the hash code current the
> > underlying
> > >>  +     * class path location.
> > >>  +     */
> > >>  +    @Override
> > >>  +    public int hashCode() {
> > >>  +        return getName().hashCode();
> > >>  +    }
> > >>  +
> > >>  +}
> > >>
> > >>
> > >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
> > >>
> ----------------------------------------------------------------------
> > >>  diff --git
> > >>
> > >
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
> > >
> > >>
> > >
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
> > >>  new file mode 100644
> > >>  index 0000000..eb56c1d
> > >>  --- /dev/null
> > >>  +++
> > >>
> > >
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
> > >>  @@ -0,0 +1,93 @@
> > >>  +/*
> > >>  + * Licensed to the Apache Software Foundation (ASF) under one
> > >>  + * or more contributor license agreements.  See the NOTICE file
> > >>  + * distributed with this work for additional information
> > >>  + * regarding copyright ownership.  The ASF licenses this file
> > >>  + * to you under the Apache License, Version 2.0 (the
> > >>  + * "License"); you may not use this file except in compliance
> > >>  + * with the License.  You may obtain a copy of the License at
> > >>  + *
> > >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> > >>  + *
> > >>  + * Unless required by applicable law or agreed to in writing,
> > >>  + * software distributed under the License is distributed on an
> > >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>  + * KIND, either express or implied.  See the License for the
> > >>  + * specific language governing permissions and limitations
> > >>  + * under the License.
> > >>  + */
> > >>  +package org.apache.tamaya.core.internal.resource;
> > >>  +
> > >>  +import org.apache.tamaya.core.resources.Resource;
> > >>  +import org.apache.tamaya.core.resources.ResourceLoader;
> > >>  +
> > >>  +import javax.annotation.Priority;
> > >>  +import java.io.File;
> > >>  +import java.net.URL;
> > >>  +import java.util.ArrayList;
> > >>  +import java.util.Collection;
> > >>  +import java.util.Enumeration;
> > >>  +import java.util.List;
> > >>  +import java.util.logging.Logger;
> > >>  +
> > >>  +/**
> > >>  + * Simple default implementation of the resource loader, which does
> > only
> > >>  support direct references to files.
> > >>  + */
> > >>  +@Priority(0)
> > >>  +public class DefaultResourceLoader implements ResourceLoader {
> > >>  +
> > >>  +    private static final Logger LOG =
> > >>  Logger.getLogger(DefaultResourceLoader.class.getName());
> > >>  +
> > >>  +    @Override
> > >>  +    public List<Resource> getResources(ClassLoader classLoader,
> > >>  Collection<String> expressions) {
> > >>  +        List<Resource> resources = new ArrayList<>();
> > >>  +        for (String expression : expressions) {
> > >>  +            if (tryClassPath(classLoader, expression, resources) ||
> > >>  tryFile(expression, resources) ||
> > >>  +                    tryURL(expression, resources)) {
> > >>  +                continue;
> > >>  +            }
> > >>  +            LOG.warning("Failed to resolve resource: " +
> > > expression);
> > >>  +        }
> > >>  +        return resources;
> > >>  +    }
> > >>  +
> > >>  +    private boolean tryClassPath(ClassLoader classLoader, String
> > > expression,
> > >>  List<Resource> resources) {
> > >>  +        try {
> > >>  +            Enumeration<URL> urls =
> > > classLoader.getResources(expression);
> > >>  +            while (urls.hasMoreElements()) {
> > >>  +                URL url = urls.nextElement();
> > >>  +                resources.add(new URLResource(url));
> > >>  +            }
> > >>  +            return !resources.isEmpty();
> > >>  +        } catch (Exception e) {
> > >>  +            LOG.finest(() -> "Failed to load resource from CP:
> > > " +
> > >>  expression);
> > >>  +        }
> > >>  +        return false;
> > >>  +    }
> > >>  +
> > >>  +    private boolean tryFile(String expression, List<Resource>
> > > resources)
> > >>  {
> > >>  +        try {
> > >>  +            File file = new File(expression);
> > >>  +            if (file.exists()) {
> > >>  +                resources.add(new FileResource(file));
> > >>  +                return true;
> > >>  +            }
> > >>  +        } catch (Exception e) {
> > >>  +            LOG.finest(() -> "Failed to load resource from file:
> > > "
> > >>  + expression);
> > >>  +        }
> > >>  +        return false;
> > >>  +    }
> > >>  +
> > >>  +    private boolean tryURL(String expression, List<Resource>
> > > resources)
> > >>  {
> > >>  +        try {
> > >>  +            URL url = new URL(expression);
> > >>  +            resources.add(new URLResource(url));
> > >>  +            return true;
> > >>  +        } catch (Exception e) {
> > >>  +            LOG.finest(() -> "Failed to load resource from file:
> > > "
> > >>  + expression);
> > >>  +        }
> > >>  +        return false;
> > >>  +
> > >>  +    }
> > >>  +
> > >>  +}
> > >>
> > >>
> > >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
> > >>
> ----------------------------------------------------------------------
> > >>  diff --git
> > >>
> > >
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
> > >>
> > >
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
> > >>  new file mode 100644
> > >>  index 0000000..e0096e5
> > >>  --- /dev/null
> > >>  +++
> > >>
> > >
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
> > >>  @@ -0,0 +1,162 @@
> > >>  +/*
> > >>  + * Licensed to the Apache Software Foundation (ASF) under one
> > >>  + * or more contributor license agreements.  See the NOTICE file
> > >>  + * distributed with this work for additional information
> > >>  + * regarding copyright ownership.  The ASF licenses this file
> > >>  + * to you under the Apache License, Version 2.0 (the
> > >>  + * "License"); you may not use this file except in compliance
> > >>  + * with the License.  You may obtain a copy of the License at
> > >>  + *
> > >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> > >>  + *
> > >>  + * Unless required by applicable law or agreed to in writing,
> > >>  + * software distributed under the License is distributed on an
> > >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>  + * KIND, either express or implied.  See the License for the
> > >>  + * specific language governing permissions and limitations
> > >>  + * under the License.
> > >>  + */
> > >>  +package org.apache.tamaya.core.internal.resource;
> > >>  +
> > >>  +import org.apache.tamaya.core.resources.Resource;
> > >>  +
> > >>  +import java.io.File;
> > >>  +import java.io.FileInputStream;
> > >>  +import java.io.IOException;
> > >>  +import java.io.InputStream;
> > >>  +import java.net.URI;
> > >>  +import java.util.Objects;
> > >>  +
> > >>  +/**
> > >>  + * Implementation of {@link
> > > org.apache.tamaya.core.resources.Resource} to
> > >>  be loaded from a file.
> > >>  + * @see java.io.File
> > >>  + */
> > >>  +public class FileResource implements Resource {
> > >>  +
> > >>  +    private final File file;
> > >>  +
> > >>  +    /**
> > >>  +     * Creates a new instance.
> > >>  +     *
> > >>  +     * @param file a File, not null.
> > >>  +     */
> > >>  +    public FileResource(File file) {
> > >>  +        this.file = Objects.requireNonNull(file, "File must not be
> > >>  null");
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * Crreates a new instance.
> > >>  +     *
> > >>  +     * @param filePath a file path
> > >>  +     */
> > >>  +    public FileResource(String filePath) {
> > >>  +        Objects.requireNonNull(filePath, "Path must not be
> > > null");
> > >>  +        this.file = new File(filePath);
> > >>  +    }
> > >>  +
> > >>  +
> > >>  +    /**
> > >>  +     * Get the file path for this resource.
> > >>  +     */
> > >>  +    public final String getPath() {
> > >>  +        return this.file.getPath();
> > >>  +    }
> > >>  +
> > >>  +
> > >>  +    /**
> > >>  +     * This implementation returns whether the underlying file
> exists.
> > >>  +     *
> > >>  +     * @see java.io.File#exists()
> > >>  +     */
> > >>  +    @Override
> > >>  +    public boolean exists() {
> > >>  +        return this.file.exists();
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * This implementation checks whether the underlying file is
> > marked as
> > >
> > >>  readable
> > >>  +     * (and corresponds to an actual file with content, not to a
> > > directory).
> > >>  +     *
> > >>  +     * @see java.io.File#canRead()
> > >>  +     * @see java.io.File#isDirectory()
> > >>  +     */
> > >>  +    @Override
> > >>  +    public boolean isAccessible() {
> > >>  +        return (this.file.canRead() && !this.file.isDirectory());
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * This implementation opens a FileInputStream for the
> underlying
> > > file.
> > >>  +     *
> > >>  +     * @see java.io.FileInputStream
> > >>  +     */
> > >>  +    @Override
> > >>  +    public InputStream getInputStream() throws IOException {
> > >>  +        return new FileInputStream(this.file);
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * This implementation returns a URI for the underlying file.
> > >>  +     *
> > >>  +     * @see java.io.File#toURI()
> > >>  +     */
> > >>  +    @Override
> > >>  +    public URI toURI() throws IOException {
> > >>  +        return this.file.toURI();
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * Returns the underlying File's length.
> > >>  +     */
> > >>  +    @Override
> > >>  +    public long length() throws IOException {
> > >>  +        return this.file.length();
> > >>  +    }
> > >>  +
> > >>  +    @Override
> > >>  +    public long lastModified() throws IOException {
> > >>  +        return file.lastModified();
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * Returns the name of the current file.
> > >>  +     *
> > >>  +     * @see java.io.File#getName()
> > >>  +     */
> > >>  +    @Override
> > >>  +    public String getName() {
> > >>  +        return this.file.getName();
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * Returns a description that includes the absolute
> > >>  +     * path of the current file.
> > >>  +     *
> > >>  +     * @see java.io.File#getAbsolutePath()
> > >>  +     */
> > >>  +    @Override
> > >>  +    public String toString() {
> > >>  +        return "File [" + this.file.getAbsolutePath() +
> > >>  "]";
> > >>  +    }
> > >>  +
> > >>  +
> > >>  +    // implementation current WritableResource
> > >>  +
> > >>  +    /**
> > >>  +     * Compares the underlying Files.
> > >>  +     */
> > >>  +    @Override
> > >>  +    public boolean equals(Object obj) {
> > >>  +        return (obj == this ||
> > >>  +                (obj instanceof FileResource &&
> > >>  this.file.equals(((FileResource) obj).file)));
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * Returns hash code current the underlying File reference.
> > >>  +     */
> > >>  +    @Override
> > >>  +    public int hashCode() {
> > >>  +        return this.file.hashCode();
> > >>  +    }
> > >>  +
> > >>  +}
> > >>
> > >>
> > >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
> > >>
> ----------------------------------------------------------------------
> > >>  diff --git
> > >>
> > >
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
> > >
> > >>
> > >
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
> > >>  new file mode 100644
> > >>  index 0000000..09510b4
> > >>  --- /dev/null
> > >>  +++
> > >>
> > >
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
> > >>  @@ -0,0 +1,117 @@
> > >>  +/*
> > >>  + * Licensed to the Apache Software Foundation (ASF) under one
> > >>  + * or more contributor license agreements.  See the NOTICE file
> > >>  + * distributed with this work for additional information
> > >>  + * regarding copyright ownership.  The ASF licenses this file
> > >>  + * to you under the Apache License, Version 2.0 (the
> > >>  + * "License"); you may not use this file except in compliance
> > >>  + * with the License.  You may obtain a copy of the License at
> > >>  + *
> > >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> > >>  + *
> > >>  + * Unless required by applicable law or agreed to in writing,
> > >>  + * software distributed under the License is distributed on an
> > >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>  + * KIND, either express or implied.  See the License for the
> > >>  + * specific language governing permissions and limitations
> > >>  + * under the License.
> > >>  + */
> > >>  +package org.apache.tamaya.core.internal.resource;
> > >>  +
> > >>  +import org.apache.tamaya.core.resources.Resource;
> > >>  +
> > >>  +import java.io.IOException;
> > >>  +import java.io.InputStream;
> > >>  +import java.net.URI;
> > >>  +import java.util.Objects;
> > >>  +
> > >>  +/**
> > >>  + * Simple Resource encapsulating an InputStream.
> > >>  + */
> > >>  +public class InputStreamResource implements Resource {
> > >>  +
> > >>  +    /** The InputStream. */
> > >>  +    private final InputStream inputStream;
> > >>  +    /** The read flag. */
> > >>  +    private boolean read = false;
> > >>  +    /** The name of the resource. */
> > >>  +    private String name;
> > >>  +
> > >>  +
> > >>  +    /**
> > >>  +     * Create a new InputStreamResource.
> > >>  +     *
> > >>  +     * @param inputStream the InputStream to use
> > >>  +     */
> > >>  +    public InputStreamResource(InputStream inputStream) {
> > >>  +        this(inputStream, "InputStream:");
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * Create a new InputStreamResource.
> > >>  +     *
> > >>  +     * @param inputStream the InputStream to use
> > >>  +     * @param name where the InputStream comes from
> > >>  +     */
> > >>  +    public InputStreamResource(InputStream inputStream, String name)
> > > {
> > >>  +        this.inputStream = Objects.requireNonNull(inputStream);
> > >>  +        this.name = (name != null ? name : "InputStream");
> > >>  +    }
> > >>  +
> > >>  +
> > >>  +    /**
> > >>  +     * This implementation always returns {@code true}.
> > >>  +     */
> > >>  +    @Override
> > >>  +    public boolean exists() {
> > >>  +        return true;
> > >>  +    }
> > >>  +
> > >>  +    @Override
> > >>  +    public URI toURI() throws IOException {
> > >>  +        throw new IOException("URI not available.");
> > >>  +    }
> > >>  +
> > >>  +    @Override
> > >>  +    public long lastModified() throws IOException {
> > >>  +        throw new IOException("lastModified not available.");
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * Accesses the input stream. Hereby the input stream can only
> > > accessed
> > >>  once.
> > >>  +     */
> > >>  +    @Override
> > >>  +    public InputStream getInputStream() throws IOException {
> > >>  +        if (this.read) {
> > >>  +            throw new IllegalStateException("InputStream can only be
> > > read
> > >>  once!");
> > >>  +        }
> > >>  +        this.read = true;
> > >>  +        return this.inputStream;
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * This implementation returns the passed-in description, if
> any.
> > >>  +     */
> > >>  +    public String toString() {
> > >>  +        return this.name != null ? this.name : super.toString();
> > >>  +    }
> > >>  +
> > >>  +
> > >>  +    /**
> > >>  +     * Compares the underlying InputStream.
> > >>  +     */
> > >>  +    @Override
> > >>  +    public boolean equals(Object obj) {
> > >>  +        return (obj == this ||
> > >>  +                (obj instanceof InputStreamResource &&
> > >>  ((InputStreamResource) obj).inputStream.equals(this.inputStream)));
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * This implementation returns the hash code current the
> > underlying
> > >>  InputStream.
> > >>  +     */
> > >>  +    @Override
> > >>  +    public int hashCode() {
> > >>  +        return this.inputStream.hashCode();
> > >>  +    }
> > >>  +
> > >>  +}
> > >>
> > >>
> > >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
> > >>
> ----------------------------------------------------------------------
> > >>  diff --git
> > >>
> > >
> >
> a/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
> > >>
> > >
> >
> b/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
> > >>  new file mode 100644
> > >>  index 0000000..4da6c53
> > >>  --- /dev/null
> > >>  +++
> > >>
> > >
> >
> b/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
> > >>  @@ -0,0 +1,37 @@
> > >>  +/*
> > >>  + * Licensed to the Apache Software Foundation (ASF) under one
> > >>  + * or more contributor license agreements.  See the NOTICE file
> > >>  + * distributed with this work for additional information
> > >>  + * regarding copyright ownership.  The ASF licenses this file
> > >>  + * to you under the Apache License, Version 2.0 (the
> > >>  + * "License"); you may not use this file except in compliance
> > >>  + * with the License.  You may obtain a copy of the License at
> > >>  + *
> > >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> > >>  + *
> > >>  + * Unless required by applicable law or agreed to in writing,
> > >>  + * software distributed under the License is distributed on an
> > >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>  + * KIND, either express or implied.  See the License for the
> > >>  + * specific language governing permissions and limitations
> > >>  + * under the License.
> > >>  + */
> > >>  +package org.apache.tamaya.core.resources;
> > >>  +
> > >>  +import java.io.IOException;
> > >>  +import java.io.InputStream;
> > >>  +
> > >>  +/**
> > >>  + * Simple interface for a component that provides data based on an
> > > InputStream.
> > >>  + */
> > >>  +@FunctionalInterface
> > >>  +public interface InputStreamSupplier {
> > >>  +
> > >>  +    /**
> > >>  +     * Access the input stream.
> > >>  +     * @return the input stream for use.
> > >>  +     * @throws IOException i the input stream could not be obtained.
> > >>  +     */
> > >>  +    InputStream getInputStream() throws IOException;
> > >>  +
> > >>  +}
> > >>
> > >>
> > >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
> > >>
> ----------------------------------------------------------------------
> > >>  diff --git
> > > a/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
> > >>  b/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
> > >>  new file mode 100644
> > >>  index 0000000..31c679d
> > >>  --- /dev/null
> > >>  +++
> b/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
> > >>  @@ -0,0 +1,115 @@
> > >>  +/*
> > >>  + * Licensed to the Apache Software Foundation (ASF) under one
> > >>  + * or more contributor license agreements.  See the NOTICE file
> > >>  + * distributed with this work for additional information
> > >>  + * regarding copyright ownership.  The ASF licenses this file
> > >>  + * to you under the Apache License, Version 2.0 (the
> > >>  + * "License"); you may not use this file except in compliance
> > >>  + * with the License.  You may obtain a copy of the License at
> > >>  + *
> > >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> > >>  + *
> > >>  + * Unless required by applicable law or agreed to in writing,
> > >>  + * software distributed under the License is distributed on an
> > >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>  + * KIND, either express or implied.  See the License for the
> > >>  + * specific language governing permissions and limitations
> > >>  + * under the License.
> > >>  + */
> > >>  +package org.apache.tamaya.core.resources;
> > >>  +
> > >>  +import java.io.File;
> > >>  +import java.io.IOException;
> > >>  +import java.io.InputStream;
> > >>  +import java.net.URI;
> > >>  +import java.net.URL;
> > >>  +import java.util.Objects;
> > >>  +
> > >>  +/**
> > >>  + * Interface for an abstract resource. The effective resource
> > > implementation
> > >>  can be completely arbitrary.
> > >>  + * By default files, classpath resources and URLs are supported, but
> > > alternate
> > >>  implementations are possible.
> > >>  + *
> > >>  + * @see #getInputStream()
> > >>  + * @see #toURI()
> > >>  + */
> > >>  +public interface Resource extends InputStreamSupplier {
> > >>  +
> > >>  +    /**
> > >>  +     * Return whether this resource actually exists. Depending on
> the
> > > resource
> > >>  this can delegate to
> > >>  +     * {@link java.io.File#exists()} or whatever may be appropriate
> > > to
> > >>  check accessibility of the resource.
> > >>  +     */
> > >>  +    default boolean exists() {
> > >>  +        // Try to open a file first, if that fails try to open the
> > > stream...
> > >>  +        try {
> > >>  +            return new File(toURI()).exists();
> > >>  +        } catch (IOException ex) {
> > >>  +            // Fallback
> > >>  +            try {
> > >>  +                InputStream is = getInputStream();
> > >>  +                is.close();
> > >>  +                return true;
> > >>  +            } catch (Exception e) {
> > >>  +                // ignore, just return false for non existing
> > >>  +                return false;
> > >>  +            }
> > >>  +        }
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * Checks whether the resource is accessible, meaning {@link
> > >>  #getInputStream()} should return a InputStream for reading the
> > >>  +     * resource's content.
> > >>  +     *
> > >>  +     * @see #getInputStream()
> > >>  +     */
> > >>  +    default boolean isAccessible() {
> > >>  +        return true;
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * Returns the resource as an URI.
> > >>  +     *
> > >>  +     * @throws IOException if the resource cannot be resolved as
> URI.
> > >>  +     */
> > >>  +    URI toURI() throws IOException;
> > >>  +
> > >>  +    /**
> > >>  +     * Determines the length for this resource.
> > >>  +     *
> > >>  +     * @throws IOException if the resource is not readable.
> > >>  +     */
> > >>  +    default long length() throws IOException {
> > >>  +        try(InputStream is = this.getInputStream();) {
> > >>  +            Objects.requireNonNull(is, "resource not
> > > available");
> > >>  +            long length = 0;
> > >>  +            byte[] buf = new byte[256];
> > >>  +            int bytesRead;
> > >>  +            while ((bytesRead = is.read(buf)) > 0) {
> > >>  +                length += bytesRead;
> > >>  +            }
> > >>  +            return length;
> > >>  +        }
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * Determine the last-modified timestamp for a resource, as UTC
> ms
> > >>  timestamp
> > >>  +     *
> > >>  +     * @throws IOException if the resource is not accessible.
> > >>  +     */
> > >>  +    default long lastModified() throws IOException{
> > >>  +        return new File(toURI()).lastModified();
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * Get a name for the resource. The name should be identifying
> the
> > > resource
> > >>  and also
> > >>  +     * never change, so it must be eligible for hashcode/equals
> > >>  implementations.
> > >>  +     */
> > >>  +    default String getName() {
> > >>  +        try {
> > >>  +            return toURI().toString();
> > >>  +        } catch (Exception e) {
> > >>  +            return toString();
> > >>  +        }
> > >>  +    }
> > >>  +
> > >>  +
> > >>  +}
> > >>  \ No newline at end of file
> > >>
> > >>
> > >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
> > >>
> ----------------------------------------------------------------------
> > >>  diff --git
> > >>
> > a/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
> > >>
> > b/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
> > >>  new file mode 100644
> > >>  index 0000000..5aff10a
> > >>  --- /dev/null
> > >>  +++
> > >
> b/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
> > >>  @@ -0,0 +1,91 @@
> > >>  +/*
> > >>  + * Licensed to the Apache Software Foundation (ASF) under one
> > >>  + * or more contributor license agreements.  See the NOTICE file
> > >>  + * distributed with this work for additional information
> > >>  + * regarding copyright ownership.  The ASF licenses this file
> > >>  + * to you under the Apache License, Version 2.0 (the
> > >>  + * "License"); you may not use this file except in compliance
> > >>  + * with the License.  You may obtain a copy of the License at
> > >>  + *
> > >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> > >>  + *
> > >>  + * Unless required by applicable law or agreed to in writing,
> > >>  + * software distributed under the License is distributed on an
> > >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>  + * KIND, either express or implied.  See the License for the
> > >>  + * specific language governing permissions and limitations
> > >>  + * under the License.
> > >>  + */
> > >>  +package org.apache.tamaya.core.resources;
> > >>  +
> > >>  +import java.util.Arrays;
> > >>  +import java.util.Collection;
> > >>  +import java.util.List;
> > >>  +
> > >>  +/**
> > >>  + * Interface to be implemented by modules. By default only direct
> > > file/resource
> > >>  resolution is supported, whereas
> > >>  + * extension modules may add functionality to perform ant styled
> > pattern
> > >>  resolution of resources.
> > >>  + */
> > >>  +public interface ResourceLoader {
> > >>  +
> > >>  +    /**
> > >>  +     * Resolves resource expressions to a list of {@link
> > >>  org.apache.tamaya.core.resources.Resource}s. Hereby
> > >>  +     * the ordering of resources matches the input of the resolved
> > > expressions.
> > >>  Nevertheless be aware that
> > >>  +     * there is no determined ordering of resources located within a
> > >>  classloader.
> > >>  +     *
> > >>  +     * @param expressions the expressions to be resolved, not empty.
> > >>  +     * @return the corresponding collection of current {@link
> > >>  org.apache.tamaya.core.resources.Resource}s found, never
> > >>  +     * null.
> > >>  +     * .
> > >>  +     */
> > >>  +    default Collection<Resource>
> > > getResources(Collection<String>
> > >>  expressions) {
> > >>  +        ClassLoader cl =
> > Thread.currentThread().getContextClassLoader();
> > >>  +        if (cl == null) {
> > >>  +            cl = getClass().getClassLoader();
> > >>  +        }
> > >>  +        return getResources(cl, expressions);
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * Resolves resource expressions to a list of {@link
> > >>  org.apache.tamaya.core.resources.Resource}s. Hereby
> > >>  +     * the ordering of resources matches the input of the resolved
> > > expressions.
> > >>  Nevertheless be aware that
> > >>  +     * there is no determined ordering of resources located within a
> > >>  classloader.
> > >>  +     *
> > >>  +     * @param expressions the expressions to be resolved, not empty.
> > >>  +     * @return the corresponding collection of current {@link
> > >>  org.apache.tamaya.core.resources.Resource}s found, never
> > >>  +     * null.
> > >>  +     * .
> > >>  +     */
> > >>  +    default Collection<Resource> getResources(String... expressions)
> > >
> > >>  {
> > >>  +        return getResources(Arrays.asList(expressions));
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * Resolves resource expressions to a list of {@link
> > >>  org.apache.tamaya.core.resources.Resource}s, considerubg
> > >>  +     * the given classloader for classloader dependent resources.
> > Hereby
> > >>  +     * the ordering of resources matches the input of the resolved
> > > expressions.
> > >>  Nevertheless be aware that
> > >>  +     * there is no determined ordering of resources located within a
> > >>  classloader.
> > >>  +     *
> > >>  +     * @param expressions the expressions to be resolved, not empty.
> > >>  +     * @return the corresponding collection of current {@link
> > >>  org.apache.tamaya.core.resources.Resource}s found, never
> > >>  +     * null.
> > >>  +     * .
> > >>  +     */
> > >>  +    default Collection<Resource> getResources(ClassLoader
> > > classLoader,
> > >>  String... expressions){
> > >>  +        return getResources(classLoader,
> Arrays.asList(expressions));
> > >>  +    }
> > >>  +
> > >>  +    /**
> > >>  +     * Resolves resource expressions to a list of {@link
> > >>  org.apache.tamaya.core.resources.Resource}s, considerubg
> > >>  +     * the given classloader for classloader dependent resources.
> > Hereby
> > >>  +     * the ordering of resources matches the input of the resolved
> > > expressions.
> > >>  Nevertheless be aware that
> > >>  +     * there is no determined ordering of resources located within a
> > >>  classloader.
> > >>  +     *
> > >>  +     * @param expressions the expressions to be resolved, not empty.
> > >>  +     * @return the corresponding collection of current {@link
> > >>  org.apache.tamaya.core.resources.Resource}s found, never
> > >>  +     * null.
> > >>  +     * .
> > >>  +     */
> > >>  +    Collection<Resource> getResources(ClassLoader classLoader,
> > >>  Collection<String> expressions);
> > >>  +
> > >>  +}
> > >>
> > >>
> > >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> > >>
> ----------------------------------------------------------------------
> > >>  diff --git
> > > a/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> > >>  b/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> > >>  index be1eadb..9c7b894 100644
> > >>  ---
> a/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> > >>  +++
> b/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> > >>  @@ -41,6 +41,12 @@ public class ConfigurationTest {
> > >>           assertEquals("Lukas",
> > >>  Configuration.current().get("name3").get());  // oderridden
> > > default
> > >>           assertEquals("Sereina",
> > >>  Configuration.current().get("name4").get()); // final only
> > >>           assertEquals("Benjamin",
> > >>  Configuration.current().get("name5").get()); // final only
> > >>  +
> > >>  +        System.out.println("name : " +
> > >>  Configuration.current().get("name").get());
> > >>  +        System.out.println("name2: " +
> > >>  Configuration.current().get("name2").get());
> > >>  +        System.out.println("name3: " +
> > >>  Configuration.current().get("name3").get());
> > >>  +        System.out.println("name4: " +
> > >>  Configuration.current().get("name4").get());
> > >>  +        System.out.println("name5: " +
> > >>  Configuration.current().get("name5").get());
> > >>       }
> > >>
> > >>
> > >>
> > >>
> > >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
> > >>
> ----------------------------------------------------------------------
> > >>  diff --git
> > >>
> > >
> >
> a/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
> > >
> > >>
> > >
> >
> b/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
> > >>  deleted file mode 100644
> > >>  index 51cc2dc..0000000
> > >>  ---
> > >>
> > >
> >
> a/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
> > >>  +++ /dev/null
> > >>  @@ -1,70 +0,0 @@
> > >>  -/*
> > >>  - * Licensed to the Apache Software Foundation (ASF) under one
> > >>  - * or more contributor license agreements.  See the NOTICE file
> > >>  - * distributed with this work for additional information
> > >>  - * regarding copyright ownership.  The ASF licenses this file
> > >>  - * to you under the Apache License, Version 2.0 (the
> > >>  - * "License"); you may not use this file except in compliance
> > >>  - * with the License.  You may obtain a copy of the License at
> > >>  - *
> > >>  - * http://www.apache.org/licenses/LICENSE-2.0
> > >>  - *
> > >>  - * Unless required by applicable law or agreed to in writing,
> > >>  - * software distributed under the License is distributed on an
> > >>  - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>  - * KIND, either express or implied.  See the License for the
> > >>  - * specific language governing permissions and limitations
> > >>  - * under the License.
> > >>  - */
> > >>  -package org.apache.tamaya.core.test.propertysource;
> > >>  -
> > >>  -import org.apache.tamaya.core.propertysource.DefaultOrdinal;
> > >>  -import
> > org.apache.tamaya.core.propertysource.EnvironmentPropertySource;
> > >>  -import org.junit.Assert;
> > >>  -import org.junit.Test;
> > >>  -
> > >>  -import java.util.Map;
> > >>  -import java.util.Optional;
> > >>  -
> > >>  -public class EnvironmentPropertySourceTest {
> > >>  -
> > >>  -    private EnvironmentPropertySource propertySource = new
> > >>  EnvironmentPropertySource();
> > >>  -
> > >>  -
> > >>  -    @Test
> > >>  -    public void testGetOrdinal() {
> > >>  -        Assert.assertEquals(DefaultOrdinal.ENVIRONMENT_PROPERTIES,
> > >>  propertySource.getOrdinal());
> > >>  -    }
> > >>  -
> > >>  -    @Test
> > >>  -    public void testGet() {
> > >>  -        String environmentPropertyToCheck =
> > >>  System.getenv().keySet().iterator().next();
> > >>  -
> > >>  -        Optional<String> value =
> > >>  propertySource.get(environmentPropertyToCheck);
> > >>  -        Assert.assertTrue(value.isPresent());
> > >>  -
> Assert.assertEquals(System.getenv(environmentPropertyToCheck),
> > >>  value.get());
> > >>  -    }
> > >>  -
> > >>  -    @Test
> > >>  -    public void testGetProperties() {
> > >>  -        Map<String, String> environmentProperties = System.getenv();
> > >>  -
> > >>  -        Assert.assertEquals(environmentProperties.size(),
> > >>  propertySource.getProperties().size());
> > >>  -
> > >>  -        for (Map.Entry<String, String> propertySourceEntry :
> > >>  propertySource.getProperties().entrySet()) {
> > >>  -            Assert.assertEquals("Entry values for key '" +
> > >>  propertySourceEntry.getKey() + "' do not match",
> > >>  -
> > >>  environmentProperties.get(propertySourceEntry.getKey()),
> > >>  propertySourceEntry.getValue());
> > >>  -        }
> > >>  -
> > >>  -        // modification is not allowed
> > >>  -        try {
> > >>  -            propertySource.getProperties().put("add.new.keys",
> > >>  "must throw exception");
> > >>  -
> Assert.fail(UnsupportedOperationException.class.getName()
> > +
> > > "
> > >>  expected");
> > >>  -        }
> > >>  -        catch (UnsupportedOperationException e) {
> > >>  -            // expected -> all is fine
> > >>  -        }
> > >>  -    }
> > >>  -
> > >>  -
> > >>  -}
> > >>
> > >>
> > >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
> > >>
> ----------------------------------------------------------------------
> > >>  diff --git
> > >>
> > >
> >
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
> > >
> > >>
> > >
> >
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
> > >>  new file mode 100644
> > >>  index 0000000..5fa90b1
> > >>  --- /dev/null
> > >>  +++
> > >>
> > >
> >
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
> > >>  @@ -0,0 +1,32 @@
> > >>  +/*
> > >>  + * Licensed to the Apache Software Foundation (ASF) under one
> > >>  + * or more contributor license agreements.  See the NOTICE file
> > >>  + * distributed with this work for additional information
> > >>  + * regarding copyright ownership.  The ASF licenses this file
> > >>  + * to you under the Apache License, Version 2.0 (the
> > >>  + * "License"); you may not use this file except in compliance
> > >>  + * with the License.  You may obtain a copy of the License at
> > >>  + *
> > >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> > >>  + *
> > >>  + * Unless required by applicable law or agreed to in writing,
> > >>  + * software distributed under the License is distributed on an
> > >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>  + * KIND, either express or implied.  See the License for the
> > >>  + * specific language governing permissions and limitations
> > >>  + * under the License.
> > >>  + */
> > >>  +package org.apache.tamaya.core.testdata;
> > >>  +
> > >>  +import org.apache.tamaya.core.PathBasedPropertySourceProvider;
> > >>  +import org.apache.tamaya.core.formats.PropertiesFormat;
> > >>  +
> > >>  +/**
> > >>  + * Test provider reading properties from
> > > classpath:cfg/defaults/**.properties.
> > >>  + */
> > >>  +public class TestPropertyDefaultSourceProvider extends
> > >>  PathBasedPropertySourceProvider{
> > >>  +
> > >>  +    public TestPropertyDefaultSourceProvider() {
> > >>  +        super("default-testdata-properties", new
> > >>  PropertiesFormat(100), "classpath:cfg/defaults/**/*.properties");
> > >>  +    }
> > >>  +}
> > >>
> > >>
> > >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
> > >>
> ----------------------------------------------------------------------
> > >>  diff --git
> > >>
> > >
> >
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
> > >>
> > >
> >
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
> > >>  deleted file mode 100644
> > >>  index d1314aa..0000000
> > >>  ---
> > >
> >
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
> > >>  +++ /dev/null
> > >>  @@ -1,55 +0,0 @@
> > >>  -/*
> > >>  - * Licensed to the Apache Software Foundation (ASF) under one
> > >>  - * or more contributor license agreements.  See the NOTICE file
> > >>  - * distributed with this work for additional information
> > >>  - * regarding copyright ownership.  The ASF licenses this file
> > >>  - * to you under the Apache License, Version 2.0 (the
> > >>  - * "License"); you may not use this file except in compliance
> > >>  - * with the License.  You may obtain a copy of the License at
> > >>  - *
> > >>  - *  http://www.apache.org/licenses/LICENSE-2.0
> > >>  - *
> > >>  - * Unless required by applicable law or agreed to in writing,
> > >>  - * software distributed under the License is distributed on an
> > >>  - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>  - * KIND, either express or implied.  See the License for the
> > >>  - * specific language governing permissions and limitations
> > >>  - * under the License.
> > >>  - */
> > >>  -package org.apache.tamaya.core.testdata;
> > >>  -
> > >>  -import java.util.HashMap;
> > >>  -import java.util.Map;
> > >>  -
> > >>  -import org.apache.tamaya.core.propertysource.BasePropertySource;
> > >>  -
> > >>  -/**
> > >>  - * Test provider reading properties from
> > > classpath:cfg/final/**.properties.
> > >>  - */
> > >>  -public class TestPropertySource extends BasePropertySource {
> > >>  -
> > >>  -    private static final Map<String, String> VALUES;
> > >>  -    static {
> > >>  -        VALUES = new HashMap<String, String>();
> > >>  -        VALUES.put("name", "Robin");
> > >>  -        VALUES.put("name2", "Sabine");
> > >>  -        VALUES.put("name3", "Lukas");
> > >>  -        VALUES.put("name4", "Sereina");
> > >>  -        VALUES.put("name5", "Benjamin");
> > >>  -    }
> > >>  -
> > >>  -
> > >>  -    public TestPropertySource() {
> > >>  -        initialzeOrdinal(100);
> > >>  -    }
> > >>  -
> > >>  -    @Override
> > >>  -    public String getName() {
> > >>  -        return "TestPropertySource";
> > >>  -    }
> > >>  -
> > >>  -    @Override
> > >>  -    public Map<String, String> getProperties() {
> > >>  -        return VALUES;
> > >>  -    }
> > >>  -}
> > >>
> > >>
> > >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
> > >>
> ----------------------------------------------------------------------
> > >>  diff --git
> > >>
> > >
> >
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
> > >
> > >>
> > >
> >
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
> > >>  new file mode 100644
> > >>  index 0000000..beafbf9
> > >>  --- /dev/null
> > >>  +++
> > >>
> > >
> >
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
> > >>  @@ -0,0 +1,32 @@
> > >>  +/*
> > >>  + * Licensed to the Apache Software Foundation (ASF) under one
> > >>  + * or more contributor license agreements.  See the NOTICE file
> > >>  + * distributed with this work for additional information
> > >>  + * regarding copyright ownership.  The ASF licenses this file
> > >>  + * to you under the Apache License, Version 2.0 (the
> > >>  + * "License"); you may not use this file except in compliance
> > >>  + * with the License.  You may obtain a copy of the License at
> > >>  + *
> > >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> > >>  + *
> > >>  + * Unless required by applicable law or agreed to in writing,
> > >>  + * software distributed under the License is distributed on an
> > >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>  + * KIND, either express or implied.  See the License for the
> > >>  + * specific language governing permissions and limitations
> > >>  + * under the License.
> > >>  + */
> > >>  +package org.apache.tamaya.core.testdata;
> > >>  +
> > >>  +import org.apache.tamaya.core.PathBasedPropertySourceProvider;
> > >>  +import org.apache.tamaya.core.formats.PropertiesFormat;
> > >>  +
> > >>  +/**
> > >>  + * Test provider reading properties from
> > > classpath:cfg/final/**.properties.
> > >>  + */
> > >>  +public class TestPropertySourceProvider extends
> > >>  PathBasedPropertySourceProvider{
> > >>  +
> > >>  +    public TestPropertySourceProvider() {
> > >>  +        super("final-testdata-properties", new
> > > PropertiesFormat(200),
> > >>  "classpath:cfg/final/**/*.properties");
> > >>  +    }
> > >>  +}
> > >>
> > >>
> > >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
> > >>
> ----------------------------------------------------------------------
> > >>  diff --git
> > >>
> > >
> >
> a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
> > >
> > >>
> > >
> >
> b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
> > >>  deleted file mode 100644
> > >>  index e6f7fad..0000000
> > >>  ---
> > >>
> > >
> >
> a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
> > >>  +++ /dev/null
> > >>  @@ -1,19 +0,0 @@
> > >>  -#
> > >>  -# Licensed to the Apache Software Foundation (ASF) under one
> > >>  -# or more contributor license agreements.  See the NOTICE file
> > >>  -# distributed with this work for additional information
> > >>  -# regarding copyright ownership.  The ASF licenses this file
> > >>  -# to you under the Apache License, Version 2.0 (the
> > >>  -# "License"); you may not use this file except in compliance
> > >>  -# with the License.  You may obtain a copy current the License at
> > >>  -#
> > >>  -#    http://www.apache.org/licenses/LICENSE-2.0
> > >>  -#
> > >>  -# Unless required by applicable law or agreed to in writing,
> > >>  -# software distributed under the License is distributed on an
> > >>  -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>  -# KIND, either express or implied.  See the License for the
> > >>  -# specific language governing permissions and limitations
> > >>  -# under the License.
> > >>  -#
> > >>  -org.apache.tamaya.core.testdata.TestPropertySource
> > >>  \ No newline at end of file
> > >>
> > >>
> > >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
> > >>
> ----------------------------------------------------------------------
> > >>  diff --git
> > >>
> > >
> >
> a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
> > >
> > >>
> > >
> >
> b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
> > >>  new file mode 100644
> > >>  index 0000000..9db0ef4
> > >>  --- /dev/null
> > >>  +++
> > >>
> > >
> >
> b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
> > >>  @@ -0,0 +1,20 @@
> > >>  +#
> > >>  +# Licensed to the Apache Software Foundation (ASF) under one
> > >>  +# or more contributor license agreements.  See the NOTICE file
> > >>  +# distributed with this work for additional information
> > >>  +# regarding copyright ownership.  The ASF licenses this file
> > >>  +# to you under the Apache License, Version 2.0 (the
> > >>  +# "License"); you may not use this file except in compliance
> > >>  +# with the License.  You may obtain a copy current the License at
> > >>  +#
> > >>  +#    http://www.apache.org/licenses/LICENSE-2.0
> > >>  +#
> > >>  +# Unless required by applicable law or agreed to in writing,
> > >>  +# software distributed under the License is distributed on an
> > >>  +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > >>  +# KIND, either express or implied.  See the License for the
> > >>  +# specific language governing permissions and limitations
> > >>  +# under the License.
> > >>  +#
> > >>  +org.apache.tamaya.core.testdata.TestPropertyDefaultSourceProvider
> > >>  +org.apache.tamaya.core.testdata.TestPropertySourceProvider
> > >>  \ No newline at end of file
> > >>
> > >
> >
>



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

Re: [2/4] incubator-tamaya git commit: TAMAYA-42, 43, 44: Readded non Spring related parts. Simplified resource API. Readded other tests.

Posted by Romain Manni-Bucau <rm...@gmail.com>.
Spring logic is more advanced - and broken IMO. It can read from a
particular jar depending syntax and where it is read from.

It brings me to the first question we should have tackled: what is a
config? For me it is all values which can be hardcoded and then cant be
packaged inside the app - otherwise you break the predicate "i dont need to
update my app for a config update". This means all classloader usages would
be excluded. If this is accepted you only need to be able to provide an URL
to an existing source to be able to read it so format is the source if it
has an URL constructor which makes thing really easier IMO.

Wdyt?
 Le 4 janv. 2015 10:09, "Mark Struberg" <st...@yahoo.de> a écrit :

> I just became aware that maybe my VOTE was not clear enough.
>
> > 2.) Wouldn't it be easier to write the functionality ourselves
> > and be able to only implement the pieces we really need?
> > Currently all we need is ClassLoader.getResources() and be done.
>
> My aim was not to implement ALL the functionality originally taken from
> Spring but really only the things we need.
> And essentially the following:
>
> > Currently all we need is ClassLoader.getResources() and be done.
>
>
> Reading Properties from a resource is essentially a single line of code:
>
>
> java.util.Properties.load(ClassLoader.getResource(fileUrl).openStream());
>
> I don't yet get the benefit of the other code. Please explain.
>
>
> LieGrue,
> strub
>
>
>
>
>
> > On Sunday, 4 January 2015, 9:10, Mark Struberg <st...@yahoo.de>
> wrote:
> > > Anatole, WHY do we need all of this?
> >
> > It is NOWHERE used!
> >
> > Why do we add 21 classes which don't provide anything useful to the
> project?
> > There was even a VOTE that we should keep it simple and just do the
> things we
> > need.
> >
> > I really don't get it. Is our goal to create a lightweight but flexible
> > configuration system or is our goal to become big and fat?
> >
> >
> > Maybe it makes sense but if so then please explain it to us.
> >
> >
> > 1.) Why do we read in a specific format?
> >
> > All the system is handling String/String and only in the last step it
> *probably*
> > gets converted into a target Type. I fail to see the benefit. Please
> explain it
> > to us.
> >
> > 2.) Why do we need all the Resource implementations?
> >
> > Java provides Resource handling out of the box. Again: we don't need any
> > scripting. So why add some handling for dynamic scenarios which we do
> not have?
> > This is basically a copy of Spring.io. But we simply don't have anything
> > scripted in XML as Spring does. So why should we add it?
> >
> >
> > I'm really tired of seeing code all over the place which is not helpful
> for
> > the project. Please don't add things we don't really need.
> >
> >
> > LieGrue,
> > strub
> >
> >
> >
> >
> >
> >
> >
> >>  On Sunday, 4 January 2015, 2:52, "anatole@apache.org"
> > <an...@apache.org> wrote:
> >>  >T AMAYA-42,43,44: Readded non Spring related parts. Simplified
> resource
> > API.
> >>  Readded other tests.
> >>
> >>
> >>  Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo
> >>  Commit:
> > http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/cc237eb4
> >>  Tree:
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/cc237eb4
> >>  Diff:
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/cc237eb4
> >>
> >>  Branch: refs/heads/master
> >>  Commit: cc237eb41b7d0c660261f451f47bbf07b7770c46
> >>  Parents: 59a9e21
> >>  Author: anatole <an...@apache.org>
> >>  Authored: Sun Jan 4 02:17:56 2015 +0100
> >>  Committer: anatole <an...@apache.org>
> >>  Committed: Sun Jan 4 02:26:23 2015 +0100
> >>
> >>  ----------------------------------------------------------------------
> >>  .../org/apache/tamaya/spi/PropertyFilter.java   |  10 +-
> >>  .../core/PathBasedPropertySourceProvider.java   |  93 ++++++++++
> >>  .../core/ResourcePropertySourceProvider.java    | 102 +++++++++++
> >>  .../core/formats/ConfigurationFormat.java       |  53 ++++++
> >>  .../tamaya/core/formats/PropertiesFormat.java   | 114 ++++++++++++
> >>  .../core/formats/PropertiesXmlFormat.java       | 115 ++++++++++++
> >>  .../core/internal/DefaultConfiguration.java     |  27 ++-
> >>  .../internal/resource/ClassPathResource.java    | 178
> +++++++++++++++++++
> >>  .../resource/DefaultResourceLoader.java         |  93 ++++++++++
> >>  .../core/internal/resource/FileResource.java    | 162 +++++++++++++++++
> >>  .../internal/resource/InputStreamResource.java  | 117 ++++++++++++
> >>  .../core/resources/InputStreamSupplier.java     |  37 ++++
> >>  .../apache/tamaya/core/resources/Resource.java  | 115 ++++++++++++
> >>  .../tamaya/core/resources/ResourceLoader.java   |  91 ++++++++++
> >>  .../apache/tamaya/core/ConfigurationTest.java   |   6 +
> >>  .../EnvironmentPropertySourceTest.java          |  70 --------
> >>  .../TestPropertyDefaultSourceProvider.java      |  32 ++++
> >>  .../core/testdata/TestPropertySource.java       |  55 ------
> >>  .../testdata/TestPropertySourceProvider.java    |  32 ++++
> >>  .../org.apache.tamaya.spi.PropertySource        |  19 --
> >>  ...org.apache.tamaya.spi.PropertySourceProvider |  20 +++
> >>  21 files changed, 1388 insertions(+), 153 deletions(-)
> >>  ----------------------------------------------------------------------
> >>
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> a/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> >>  b/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> >>  index 7479008..c8626fc 100644
> >>  --- a/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> >>  +++ b/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> >>  @@ -19,7 +19,7 @@
> >>  package org.apache.tamaya.spi;
> >>
> >>
> >>  -import java.util.Map;
> >>  +import java.util.function.Function;
> >>
> >>  /**
> >>    * <p>Interface for filtering the current map of properties during
> > the
> >>  evaluation of the chain of PropertySources.
> >>  @@ -27,7 +27,7 @@ import java.util.Map;
> >>    * hereby is defined by the corresponding {@code @Priority}
> >>  annotation.</p>
> >>    * <p>Filters </p>
> >>    */
> >>  -public interface PropertyFilter<T>{
> >>  +public interface PropertyFilter{
> >>
> >>       /**
> >>        * <p>Maps the current {@code valueToBeFiltered} value to a
> > new
> >>  value. The resulting value will be used as the result
> >>  @@ -44,10 +44,10 @@ public interface PropertyFilter<T>{
> >>        *
> >>        * @param key the key accessed, not null.
> >>        * @param valueToBeFiltered the value to be filtered, not null.
> >>  -     * @param currentMap the current input property map, not null.
> Can be
> > used
> >>  for resolution of the filtered value
> >>  -     *                   or as datasource for additional
> meta-information,
> > such
> >>  as categories, sensitivity etc.
> >>  +     * @param propertyValueProvider accessor for reading additional
> (eg
> >>  metadata) properties to perform correct
> >>  +     *                              filtering, never null.
> >>        * @return the filtered map, never null.
> >>        */
> >>  -    String filterProperty(String key, String valueToBeFiltered,
> >>  Map<String,String> currentMap);
> >>  +    String filterProperty(String key, String valueToBeFiltered,
> >>  Function<String,String> propertyValueProvider);
> >>
> >>  }
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
> >
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
> >>  new file mode 100644
> >>  index 0000000..31dbf4b
> >>  --- /dev/null
> >>  +++
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
> >>  @@ -0,0 +1,93 @@
> >>  +/*
> >>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>  + * or more contributor license agreements.  See the NOTICE file
> >>  + * distributed with this work for additional information
> >>  + * regarding copyright ownership.  The ASF licenses this file
> >>  + * to you under the Apache License, Version 2.0 (the
> >>  + * "License"); you may not use this file except in compliance
> >>  + * with the License.  You may obtain a copy of the License at
> >>  + *
> >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>  + *
> >>  + * Unless required by applicable law or agreed to in writing,
> >>  + * software distributed under the License is distributed on an
> >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  + * KIND, either express or implied.  See the License for the
> >>  + * specific language governing permissions and limitations
> >>  + * under the License.
> >>  + */
> >>  +package org.apache.tamaya.core;
> >>  +
> >>  +import org.apache.tamaya.core.formats.ConfigurationFormat;
> >>  +import org.apache.tamaya.core.resources.Resource;
> >>  +import org.apache.tamaya.core.resources.ResourceLoader;
> >>  +import org.apache.tamaya.spi.PropertySource;
> >>  +import org.apache.tamaya.spi.PropertySourceProvider;
> >>  +import org.apache.tamaya.spi.ServiceContext;
> >>  +
> >>  +import java.util.ArrayList;
> >>  +import java.util.Arrays;
> >>  +import java.util.Collection;
> >>  +import java.util.List;
> >>  +import java.util.Objects;
> >>  +import java.util.logging.Level;
> >>  +import java.util.logging.Logger;
> >>  +
> >>  +/**
> >>  + * Implementation of a {@link PropertySourceProvider} that reads
> >>  configuration from some given resource paths
> >>  + * and using the given formats. The resource path are resolved using
> the
> >>  current
> >>  + * {@link org.apache.tamaya.core.resources.ResourceLoader} active.
> >>  + */
> >>  +public class PathBasedPropertySourceProvider implements
> > PropertySourceProvider
> >>  {
> >>  +    /** The logger used. */
> >>  +    private static final Logger LOG =
> >>  Logger.getLogger(PathBasedPropertySourceProvider.class.getName());
> >>  +    /** The property source base name, will be used for creating a
> useful
> > name
> >>  of the
> >>  +     * {@link org.apache.tamaya.spi.PropertySource} created. */
> >>  +    private String sourceName;
> >>  +    /** The config formats supported for the given location/resource
> > paths. */
> >>  +    private List<ConfigurationFormat> configFormats = new
> >>  ArrayList<>();
> >>  +    /** The paths to be evaluated. */
> >>  +    private List<String> paths = new ArrayList<>();
> >>  +
> >>  +    /**
> >>  +     * Creates a new instance.
> >>  +     * @param sourceName the base name of the configuration, used for
> > creating
> >>  PropertySource child names.
> >>  +     * @param formats the formats to be used, not null, not empty.
> >>  +     * @param paths the paths to be resolved, not null, not empty.
> >>  +     */
> >>  +    public PathBasedPropertySourceProvider(String sourceName,
> >>  List<ConfigurationFormat> formats, String... paths) {
> >>  +        this.sourceName = Objects.requireNonNull(sourceName);
> >>  +        this.configFormats.addAll(Objects.requireNonNull(formats));
> >>  +
> this.paths.addAll(Arrays.asList(Objects.requireNonNull(paths)));
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Creates a new instance.
> >>  +     * @param sourceName the base name of the configuration, used for
> > creating
> >>  PropertySource child names.
> >>  +     * @param format the format to be used.
> >>  +     * @param paths the paths to be resolved, not null, not empty.
> >>  +     */
> >>  +    public PathBasedPropertySourceProvider(String sourceName,
> >>  ConfigurationFormat format, String... paths) {
> >>  +        this.sourceName = Objects.requireNonNull(sourceName);
> >>  +        this.configFormats.add(Objects.requireNonNull(format));
> >>  +
> this.paths.addAll(Arrays.asList(Objects.requireNonNull(paths)));
> >>  +    }
> >>  +
> >>  +    @Override
> >>  +    public Collection<PropertySource> getPropertySources() {
> >>  +        List<PropertySource> propertySources = new
> > ArrayList<>();
> >>  +        paths.forEach((path) -> {
> >>  +            for (Resource res :
> >>
> >
> ServiceContext.getInstance().getService(ResourceLoader.class).get().getResources(path))
> >
> >>  {
> >>  +                try {
> >>  +                    for (ConfigurationFormat format : configFormats)
> > {
> >>  +
> >>  propertySources.addAll(format.readConfiguration(sourceName, res));
> >>  +                    }
> >>  +                } catch (Exception e) {
> >>  +                    LOG.log(Level.WARNING, "Failed to add resource
> > based
> >>  config: " + res.getName(), e);
> >>  +                }
> >>  +            }
> >>  +        });
> >>  +        return propertySources;
> >>  +    }
> >>  +
> >>  +}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
> >>  new file mode 100644
> >>  index 0000000..de6b578
> >>  --- /dev/null
> >>  +++
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
> >>  @@ -0,0 +1,102 @@
> >>  +/*
> >>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>  + * or more contributor license agreements.  See the NOTICE file
> >>  + * distributed with this work for additional information
> >>  + * regarding copyright ownership.  The ASF licenses this file
> >>  + * to you under the Apache License, Version 2.0 (the
> >>  + * "License"); you may not use this file except in compliance
> >>  + * with the License.  You may obtain a copy of the License at
> >>  + *
> >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>  + *
> >>  + * Unless required by applicable law or agreed to in writing,
> >>  + * software distributed under the License is distributed on an
> >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  + * KIND, either express or implied.  See the License for the
> >>  + * specific language governing permissions and limitations
> >>  + * under the License.
> >>  + */
> >>  +package org.apache.tamaya.core;
> >>  +
> >>  +import org.apache.tamaya.core.formats.ConfigurationFormat;
> >>  +import org.apache.tamaya.core.resources.Resource;
> >>  +import org.apache.tamaya.spi.PropertySource;
> >>  +import org.apache.tamaya.spi.PropertySourceProvider;
> >>  +
> >>  +import java.util.ArrayList;
> >>  +import java.util.Arrays;
> >>  +import java.util.Collection;
> >>  +import java.util.List;
> >>  +import java.util.Objects;
> >>  +import java.util.logging.Logger;
> >>  +
> >>  +/**
> >>  + * Implementation of a {@link
> >>  org.apache.tamaya.spi.PropertySourceProvider} that is based on a single
> > resource
> >>  + * and a number of formats.
> >>  + */
> >>  +public class ResourcePropertySourceProvider implements
> > PropertySourceProvider
> >>  {
> >>  +    /** The logger used. */
> >>  +    private static final Logger LOG =
> >>  Logger.getLogger(ResourcePropertySourceProvider.class.getName());
> >>  +    /** The supported formats. */
> >>  +    private List<ConfigurationFormat> formats = new
> > ArrayList<>();
> >>  +    /** The resource. */
> >>  +    private Resource resource;
> >>  +    /** The source name used for creating the PropertySource names. */
> >>  +    private String sourceName;
> >>  +
> >>  +    /**
> >>  +     * Creates a new instance.
> >>  +     * @param resource the {@link
> >>  org.apache.tamaya.core.resources.Resource}, not null.
> >>  +     * @param formats the supported formats, not empty.
> >>  +     */
> >>  +    public ResourcePropertySourceProvider(String sourceName, Resource
> > resource,
> >>  ConfigurationFormat... formats) {
> >>  +        this(sourceName, resource, Arrays.asList(formats));
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Creates a new instance.
> >>  +     * @param resource the {@link
> >>  org.apache.tamaya.core.resources.Resource}, not null.
> >>  +     * @param formats the supported formats, not empty.
> >>  +     */
> >>  +    public ResourcePropertySourceProvider(String sourceName, Resource
> > resource,
> >>  List<ConfigurationFormat> formats) {
> >>  +        this.resource = Objects.requireNonNull(resource);
> >>  +        this.sourceName = Objects.requireNonNull(sourceName);
> >>  +        if(formats.size()==0){
> >>  +            throw new IllegalArgumentException("Format
> > required.");
> >>  +        }
> >>  +        this.formats.addAll(formats);
> >>  +    }
> >>  +
> >>  +
> >>  +    /**
> >>  +     * Get the underlying resource.
> >>  +     *
> >>  +     * @return the underlying resource, never null.
> >>  +     */
> >>  +    public Resource getResource() {
> >>  +        return this.resource;
> >>  +    }
> >>  +
> >>  +
> >>  +    @Override
> >>  +    public String toString() {
> >>  +        return "ResourcePropertySourceProvider{" +
> >>  +                "resource=" + resource +
> >>  +                ", formats=+" + formats +
> >>  +                '}';
> >>  +    }
> >>  +
> >>  +    @Override
> >>  +    public Collection<PropertySource> getPropertySources() {
> >>  +        List<PropertySource> propertySources = new
> > ArrayList<>();
> >>  +        for (ConfigurationFormat format : formats) {
> >>  +            try {
> >>  +
> > propertySources.addAll(format.readConfiguration(sourceName,
> >>  resource));
> >>  +            } catch (Exception e) {
> >>  +                LOG.info(() -> "Format was not matching: " +
> >>  format + " for resource: " + resource.getName());
> >>  +            }
> >>  +        }
> >>  +        return propertySources;
> >>  +    }
> >>  +
> >>  +}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
> >>  new file mode 100644
> >>  index 0000000..5d289bb
> >>  --- /dev/null
> >>  +++
> >
> b/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
> >>  @@ -0,0 +1,53 @@
> >>  +/*
> >>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>  + * or more contributor license agreements.  See the NOTICE file
> >>  + * distributed with this work for additional information
> >>  + * regarding copyright ownership.  The ASF licenses this file
> >>  + * to you under the Apache License, Version 2.0 (the
> >>  + * "License"); you may not use this file except in compliance
> >>  + * with the License.  You may obtain a copy of the License at
> >>  + *
> >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>  + *
> >>  + * Unless required by applicable law or agreed to in writing,
> >>  + * software distributed under the License is distributed on an
> >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  + * KIND, either express or implied.  See the License for the
> >>  + * specific language governing permissions and limitations
> >>  + * under the License.
> >>  + */
> >>  +package org.apache.tamaya.core.formats;
> >>  +
> >>  +import org.apache.tamaya.core.resources.Resource;
> >>  +import org.apache.tamaya.spi.PropertySource;
> >>  +
> >>  +import java.io.IOException;
> >>  +import java.util.Collection;
> >>  +
> >>  +/**
> >>  + * Implementations current this class encapsulate the mechanism how to
> > read a
> >>  + * resource including interpreting the format correctly (e.g. xml vs.
> >>  + * properties). In most cases file only contains entries of the same
> > priority,
> >>  which would then
> >>  + * result in only one {@link PropertySource}. Complex file formats,
> >>  hoiwever, may contain entries
> >>  + * of different priorities. In this cases, each ordinal type found
> must be
> >
> >>  returned as a separate
> >>  + * {@link PropertySource} instance.
> >>  + */
> >>  +@FunctionalInterface
> >>  +public interface ConfigurationFormat {
> >>  +
> >>  +    /**
> >>  +     * Reads a list {@link org.apache.tamaya.spi.PropertySource}
> > instances
> >>  from a resource, using this format.
> >>  +     * If the configuration format only contains entries of one
> ordinal
> > type,
> >>  normally only one single
> >>  +     * instance of PropertySource is returned. Nevertheless custom
> formats
> > may
> >>  contain different sections or parts,
> >>  +     * where each part maps to a different target rdinal (eg defaults,
> > domain
> >>  config and app config). In the
> >>  +     * ladder case multiple PropertySources can be returned, each one
> with
> > its
> >>  own ordinal and the corresponding
> >>  +     * entries.
> >>  +     *
> >>  +     * @param sourceName name to be used for constructing a useful
> name
> > for the
> >>  created
> >>  +     *                   {@link org.apache.tamaya.spi.PropertySource}
> >
> >>  instances.
> >>  +     * @param resource   the configuration resource, not null
> >>  +     * @return the corresponding {@link
> >>  org.apache.tamaya.spi.PropertySource} instances, never {@code null}.
> >>  +     */
> >>  +    Collection<PropertySource> readConfiguration(String sourceName,
> >>  Resource resource) throws IOException;
> >>  +
> >>  +}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> a/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
> >>
> b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
> >>  new file mode 100644
> >>  index 0000000..3584f8e
> >>  --- /dev/null
> >>  +++
> > b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
> >>  @@ -0,0 +1,114 @@
> >>  +/*
> >>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>  + * or more contributor license agreements.  See the NOTICE file
> >>  + * distributed with this work for additional information
> >>  + * regarding copyright ownership.  The ASF licenses this file
> >>  + * to you under the Apache License, Version 2.0 (the
> >>  + * "License"); you may not use this file except in compliance
> >>  + * with the License.  You may obtain a copy of the License at
> >>  + *
> >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>  + *
> >>  + * Unless required by applicable law or agreed to in writing,
> >>  + * software distributed under the License is distributed on an
> >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  + * KIND, either express or implied.  See the License for the
> >>  + * specific language governing permissions and limitations
> >>  + * under the License.
> >>  + */
> >>  +package org.apache.tamaya.core.formats;
> >>  +
> >>  +import org.apache.tamaya.core.resources.Resource;
> >>  +import org.apache.tamaya.spi.PropertySource;
> >>  +
> >>  +import java.io.InputStream;
> >>  +import java.util.ArrayList;
> >>  +import java.util.Collection;
> >>  +import java.util.Collections;
> >>  +import java.util.List;
> >>  +import java.util.Map;
> >>  +import java.util.Optional;
> >>  +import java.util.Properties;
> >>  +import java.util.logging.Level;
> >>  +import java.util.logging.Logger;
> >>  +
> >>  +/**
> >>  + * Implementation of a {@link
> >>  org.apache.tamaya.core.formats.ConfigurationFormat} for -properties
> files.
> >>  + *
> >>  + * @see java.util.Properties#load(java.io.InputStream)
> >>  + */
> >>  +public class PropertiesFormat implements ConfigurationFormat {
> >>  +    /**
> >>  +     * The logger.
> >>  +     */
> >>  +    private final static Logger LOG =
> >>  Logger.getLogger(PropertiesFormat.class.getName());
> >>  +
> >>  +    /**
> >>  +     * The target ordinal.
> >>  +     */
> >>  +    private int ordinal;
> >>  +
> >>  +    /**
> >>  +     * Creates a new format instance, hereby producing entries with
> the
> > given
> >>  ordinal, if not overridden by the
> >>  +     * configuration itself.
> >>  +     * TODO document and implement override feature
> >>  +     * @param ordinal the target ordinal.
> >>  +     */
> >>  +    public PropertiesFormat(int ordinal) {
> >>  +        this.ordinal = ordinal;
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Get the target ordinal, produced by this format.
> >>  +     *
> >>  +     * @return the target ordinal
> >>  +     */
> >>  +    public int getOrdinal() {
> >>  +        return ordinal;
> >>  +    }
> >>  +
> >>  +    @SuppressWarnings("unchecked")
> >>  +    @Override
> >>  +    public Collection<PropertySource> readConfiguration(String
> > baseName,
> >>  Resource resource) {
> >>  +        final String sourceName =
> >>  (baseName==null?"Properties:":baseName) + resource.getName();
> >>  +        if (resource.exists()) {
> >>  +            List<PropertySource> propertySources = new
> >>  ArrayList<>();
> >>  +            try (InputStream is = resource.getInputStream()) {
> >>  +                final Properties p = new Properties();
> >>  +                p.load(is);
> >>  +                propertySources.add(new PropertySource() {
> >>  +                    @Override
> >>  +                    public int getOrdinal() {
> >>  +                        return ordinal;
> >>  +                    }
> >>  +
> >>  +                    @Override
> >>  +                    public String getName() {
> >>  +                        return sourceName;
> >>  +                    }
> >>  +
> >>  +                    @Override
> >>  +                    public Optional<String> get(String key) {
> >>  +                        return
> Optional.ofNullable(p.getProperty(key));
> >>  +                    }
> >>  +
> >>  +                    @Override
> >>  +                    public Map<String, String> getProperties()
> > {
> >>  +                        return Map.class.cast(p);
> >>  +                    }
> >>  +                });
> >>  +                return propertySources;
> >>  +            } catch (Exception e) {
> >>  +                LOG.log(Level.FINEST, e, () -> "Failed to read
> > config
> >>  from resource: " + resource);
> >>  +            }
> >>  +        }
> >>  +        return Collections.emptyList();
> >>  +    }
> >>  +
> >>  +    @Override
> >>  +    public String toString() {
> >>  +        return "PropertiesFormat{" +
> >>  +                "ordinal=" + ordinal +
> >>  +                '}';
> >>  +    }
> >>  +}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
> >>  new file mode 100644
> >>  index 0000000..3f77810
> >>  --- /dev/null
> >>  +++
> >
> b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
> >>  @@ -0,0 +1,115 @@
> >>  +/*
> >>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>  + * or more contributor license agreements.  See the NOTICE file
> >>  + * distributed with this work for additional information
> >>  + * regarding copyright ownership.  The ASF licenses this file
> >>  + * to you under the Apache License, Version 2.0 (the
> >>  + * "License"); you may not use this file except in compliance
> >>  + * with the License.  You may obtain a copy of the License at
> >>  + *
> >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>  + *
> >>  + * Unless required by applicable law or agreed to in writing,
> >>  + * software distributed under the License is distributed on an
> >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  + * KIND, either express or implied.  See the License for the
> >>  + * specific language governing permissions and limitations
> >>  + * under the License.
> >>  + */
> >>  +package org.apache.tamaya.core.formats;
> >>  +
> >>  +import org.apache.tamaya.core.resources.Resource;
> >>  +import org.apache.tamaya.spi.PropertySource;
> >>  +
> >>  +import java.io.InputStream;
> >>  +import java.util.ArrayList;
> >>  +import java.util.Collection;
> >>  +import java.util.Collections;
> >>  +import java.util.List;
> >>  +import java.util.Map;
> >>  +import java.util.Optional;
> >>  +import java.util.Properties;
> >>  +import java.util.logging.Level;
> >>  +import java.util.logging.Logger;
> >>  +
> >>  +/**
> >>  + * Implementation of a {@link
> >>  org.apache.tamaya.core.formats.ConfigurationFormat} for xml property
> >>  + * files.
> >>  + *
> >>  + * @see java.util.Properties#loadFromXML(java.io.InputStream)
> >>  + */
> >>  +public class PropertiesXmlFormat implements ConfigurationFormat {
> >>  +    /**
> >>  +     * The logger.
> >>  +     */
> >>  +    private final static Logger LOG =
> >>  Logger.getLogger(PropertiesXmlFormat.class.getName());
> >>  +
> >>  +    /**
> >>  +     * The target ordinal.
> >>  +     */
> >>  +    private int ordinal;
> >>  +
> >>  +    /**
> >>  +     * Creates a new format instance, producing entries for the given
> > ordinal,
> >>  if not overridden by a
> >>  +     * config entry itself.
> >>  +     * TODO document and implement override feature
> >>  +     * @param ordinal the target ordinal.
> >>  +     */
> >>  +    public PropertiesXmlFormat(int ordinal) {
> >>  +        this.ordinal = ordinal;
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Get the target ordinal, produced by this format.
> >>  +     *
> >>  +     * @return the target ordinal
> >>  +     */
> >>  +    public int getOrdinal() {
> >>  +        return ordinal;
> >>  +    }
> >>  +
> >>  +    @SuppressWarnings("unchecked")
> >>  +    @Override
> >>  +    public Collection<PropertySource> readConfiguration(String
> > baseName,
> >>  Resource resource) {
> >>  +        if (resource.exists()) {
> >>  +            final String sourceName =
> >>  (baseName==null?"Properties:":baseName) + resource.getName();
> >>  +            List<PropertySource> propertySources = new
> >>  ArrayList<>();
> >>  +            try (InputStream is = resource.getInputStream()) {
> >>  +                final Properties p = new Properties();
> >>  +                p.loadFromXML(is);
> >>  +                propertySources.add(new PropertySource() {
> >>  +                    @Override
> >>  +                    public int getOrdinal() {
> >>  +                        return ordinal;
> >>  +                    }
> >>  +
> >>  +                    @Override
> >>  +                    public String getName() {
> >>  +                        return sourceName;
> >>  +                    }
> >>  +
> >>  +                    @Override
> >>  +                    public Optional<String> get(String key) {
> >>  +                        return
> Optional.ofNullable(p.getProperty(key));
> >>  +                    }
> >>  +
> >>  +                    @Override
> >>  +                    public Map<String, String> getProperties()
> > {
> >>  +                        return Map.class.cast(p);
> >>  +                    }
> >>  +                });
> >>  +                return propertySources;
> >>  +            } catch (Exception e) {
> >>  +                LOG.log(Level.FINEST, e, () -> "Failed to read
> > config
> >>  from resource: " + resource);
> >>  +            }
> >>  +        }
> >>  +        return Collections.emptyList();
> >>  +    }
> >>  +
> >>  +    @Override
> >>  +    public String toString() {
> >>  +        return "PropertiesXmlFormat{" +
> >>  +                "ordinal=" + ordinal +
> >>  +                '}';
> >>  +    }
> >>  +}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> >>  index 0a39b7d..3769e27 100644
> >>  ---
> >>
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> >>  +++
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> >>  @@ -22,6 +22,7 @@ import org.apache.tamaya.ConfigException;
> >>  import org.apache.tamaya.Configuration;
> >>  import org.apache.tamaya.spi.ConfigurationContext;
> >>  import org.apache.tamaya.spi.PropertyConverter;
> >>  +import org.apache.tamaya.spi.PropertyFilter;
> >>  import org.apache.tamaya.spi.PropertySource;
> >>  import org.apache.tamaya.spi.ServiceContext;
> >>
> >>  @@ -33,6 +34,7 @@ import java.util.Map;
> >>  import java.util.Optional;
> >>  import java.util.logging.Level;
> >>  import java.util.logging.Logger;
> >>  +import java.util.stream.Collectors;
> >>
> >>  /**
> >>    * Implementation of the Configuration API. This class uses the
> current
> >>  {@link ConfigurationContext} to evaluate the
> >>  @@ -56,13 +58,21 @@ public class DefaultConfiguration implements
> > Configuration
> >>  {
> >>       @Override
> >>       public Optional<String> get(String key) {
> >>           List<PropertySource> propertySources =
> >>
> >
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertySources();
> >>  +        String unfilteredValue = null;
> >>           for (PropertySource propertySource : propertySources) {
> >>               Optional<String> value = propertySource.get(key);
> >>               if (value.isPresent()) {
> >>  -                return value;
> >>  +                unfilteredValue = value.get();
> >>  +                break;
> >>               }
> >>           }
> >>  -        return Optional.empty();
> >>  +        // Apply filters to values, prevent values filtered to null!
> >>  +        for(PropertyFilter filter:
> >>  +
> >>
> >
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyFilters()){
> >>  +            unfilteredValue = filter.filterProperty(key,
> unfilteredValue,
> >>  +                    (String k) ->
> > key.equals(k)?null:get(k).orElse(null));
> >>  +        }
> >>  +        return Optional.ofNullable(unfilteredValue);
> >>       }
> >>
> >>       @Override
> >>  @@ -83,7 +93,15 @@ public class DefaultConfiguration implements
> > Configuration
> >>  {
> >>                   LOG.log(Level.SEVERE, "Error adding properties from
> >>  PropertySource: " + propertySource +", ignoring
> > PropertySource.",
> >>  e);
> >>               }
> >>           }
> >>  -        return result;
> >>  +        // Apply filters to values, prevent values filtered to null!
> >>  +        for(PropertyFilter filter:
> >>  +
> >>
> >
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyFilters()){
> >>  +            result.replaceAll((k,v) -> filter.filterProperty(k, v,
> >>  +                    (String k2) ->
> > k2.equals(k)?null:get(k2).orElse(null)));
> >>  +        }
> >>  +        // Remove null values
> >>  +        return result.entrySet().parallelStream().filter((e) ->
> >>  e.getValue()!=null).collect(
> >>  +                Collectors.toMap((e) -> e.getKey(), (e) ->
> >>  e.getValue()));
> >>       }
> >>
> >>       /**
> >>  @@ -101,7 +119,8 @@ public class DefaultConfiguration implements
> > Configuration
> >>  {
> >>       public <T> Optional<T> get(String key, Class<T>
> > type)
> >>  {
> >>           Optional<String> value = get(key);
> >>           if (value.isPresent()) {
> >>  -            List<PropertyConverter<T>> converters =
> >>
> >
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyConverters(type);
> >>  +            List<PropertyConverter<T>> converters =
> >>  ServiceContext.getInstance().getService(ConfigurationContext.class)
> >>  +                    .get().getPropertyConverters(type);
> >>               for (PropertyConverter<T> converter : converters) {
> >>                   try {
> >>                       T t = converter.convert(value.get());
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
> >
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
> >>  new file mode 100644
> >>  index 0000000..21806cd
> >>  --- /dev/null
> >>  +++
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
> >>  @@ -0,0 +1,178 @@
> >>  +/*
> >>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>  + * or more contributor license agreements.  See the NOTICE file
> >>  + * distributed with this work for additional information
> >>  + * regarding copyright ownership.  The ASF licenses this file
> >>  + * to you under the Apache License, Version 2.0 (the
> >>  + * "License"); you may not use this file except in compliance
> >>  + * with the License.  You may obtain a copy of the License at
> >>  + *
> >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>  + *
> >>  + * Unless required by applicable law or agreed to in writing,
> >>  + * software distributed under the License is distributed on an
> >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  + * KIND, either express or implied.  See the License for the
> >>  + * specific language governing permissions and limitations
> >>  + * under the License.
> >>  + */
> >>  +package org.apache.tamaya.core.internal.resource;
> >>  +
> >>  +import org.apache.tamaya.core.resources.Resource;
> >>  +
> >>  +import java.io.IOException;
> >>  +import java.io.InputStream;
> >>  +import java.net.URI;
> >>  +import java.net.URISyntaxException;
> >>  +import java.net.URL;
> >>  +import java.util.Objects;
> >>  +
> >>  +/**
> >>  + * Implementation of {@link Resource} to be loaded from the
> > classpath.
> >>  + */
> >>  +public class ClassPathResource implements Resource {
> >>  +
> >>  +    private final String path;
> >>  +
> >>  +    private ClassLoader classLoader;
> >>  +
> >>  +
> >>  +    /**
> >>  +     * Create a new resource using the current context class loader.
> >>  +     *
> >>  +     * @param path the resource path, not null
> >>  +     * @see java.lang.ClassLoader#getResourceAsStream(String)
> >>  +     */
> >>  +    public ClassPathResource(String path) {
> >>  +        this(path, (ClassLoader) null);
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Create a new resource using the given class loader.
> >>  +     *
> >>  +     * @param path        the resource path, not null
> >>  +     * @param classLoader the class loader to load the resource with,
> >>  +     *                    or {@code null} for the current context
> > class
> >>  loader
> >>  +     * @see ClassLoader#getResourceAsStream(String)
> >>  +     */
> >>  +    public ClassPathResource(String path, ClassLoader classLoader) {
> >>  +        Objects.requireNonNull(path, "Path null");
> >>  +        if (path.startsWith("/")) {
> >>  +            path = path.substring(1);
> >>  +        }
> >>  +        this.path = path.trim();
> >>  +        if(classLoader==null){
> >>  +            classLoader =
> Thread.currentThread().getContextClassLoader();
> >>  +        }
> >>  +        if(classLoader==null){
> >>  +            classLoader = getClass().getClassLoader();
> >>  +        }
> >>  +        this.classLoader = classLoader;
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * @return the path for this resource.
> >>  +     */
> >>  +    public final String getPath() {
> >>  +        return this.path;
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * @return the ClassLoader that this resource will be accessed
> from.
> >>  +     */
> >>  +    public final ClassLoader getClassLoader() {
> >>  +        return this.classLoader;
> >>  +    }
> >>  +
> >>  +
> >>  +    /**
> >>  +     * Checks if the given resource is resolvable from the configured
> >>  classloader.
> >>  +     *
> >>  +     * @see java.lang.ClassLoader#getResource(String)
> >>  +     */
> >>  +    @Override
> >>  +    public boolean exists() {
> >>  +        return (resolveURL() != null);
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Resolves a URL for the underlying class path resource.
> >>  +     *
> >>  +     * @return the resolved URL, or {@code null}
> >>  +     */
> >>  +    protected URL resolveURL() {
> >>  +        return this.classLoader.getResource(this.path);
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * This implementation opens an InputStream for the given class
> path
> >>  resource.
> >>  +     *
> >>  +     * @see java.lang.ClassLoader#getResourceAsStream(String)
> >>  +     * @see java.lang.Class#getResourceAsStream(String)
> >>  +     */
> >>  +    @Override
> >>  +    public InputStream getInputStream() throws IOException {
> >>  +        InputStream is =
> this.classLoader.getResourceAsStream(this.path);
> >>  +        if (is == null) {
> >>  +            throw new IOException(getName() + " does not
> > exist");
> >>  +        }
> >>  +        return is;
> >>  +    }
> >>  +
> >>  +    @Override
> >>  +    public URI toURI() throws IOException {
> >>  +        try {
> >>  +            return resolveURL().toURI();
> >>  +        } catch (URISyntaxException e) {
> >>  +            throw new IOException(e);
> >>  +        }
> >>  +    }
> >>  +
> >>  +    @Override
> >>  +    public long lastModified() throws IOException {
> >>  +        return 0;
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * This implementation returns the name current the file that this
> > class
> >>  path
> >>  +     * resource refers to.
> >>  +     */
> >>  +    @Override
> >>  +    public String getName() {
> >>  +        return "classpath:"+path;
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * This implementation returns a description that includes the
> class
> > path
> >>  location.
> >>  +     */
> >>  +    @Override
> >>  +    public String toString() {
> >>  +        return "ClassPathResource[" + path + ']';
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * This implementation compares the underlying class path
> locations.
> >>  +     */
> >>  +    @Override
> >>  +    public boolean equals(Object obj) {
> >>  +        if (obj == this) {
> >>  +            return true;
> >>  +        }
> >>  +        if (obj instanceof ClassPathResource) {
> >>  +            ClassPathResource otherRes = (ClassPathResource) obj;
> >>  +            return (this.path.equals(otherRes.path) &&
> >>  +                    Objects.equals(this.classLoader,
> > otherRes.classLoader));
> >>  +        }
> >>  +        return false;
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * This implementation returns the hash code current the
> underlying
> >>  +     * class path location.
> >>  +     */
> >>  +    @Override
> >>  +    public int hashCode() {
> >>  +        return getName().hashCode();
> >>  +    }
> >>  +
> >>  +}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
> >
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
> >>  new file mode 100644
> >>  index 0000000..eb56c1d
> >>  --- /dev/null
> >>  +++
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
> >>  @@ -0,0 +1,93 @@
> >>  +/*
> >>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>  + * or more contributor license agreements.  See the NOTICE file
> >>  + * distributed with this work for additional information
> >>  + * regarding copyright ownership.  The ASF licenses this file
> >>  + * to you under the Apache License, Version 2.0 (the
> >>  + * "License"); you may not use this file except in compliance
> >>  + * with the License.  You may obtain a copy of the License at
> >>  + *
> >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>  + *
> >>  + * Unless required by applicable law or agreed to in writing,
> >>  + * software distributed under the License is distributed on an
> >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  + * KIND, either express or implied.  See the License for the
> >>  + * specific language governing permissions and limitations
> >>  + * under the License.
> >>  + */
> >>  +package org.apache.tamaya.core.internal.resource;
> >>  +
> >>  +import org.apache.tamaya.core.resources.Resource;
> >>  +import org.apache.tamaya.core.resources.ResourceLoader;
> >>  +
> >>  +import javax.annotation.Priority;
> >>  +import java.io.File;
> >>  +import java.net.URL;
> >>  +import java.util.ArrayList;
> >>  +import java.util.Collection;
> >>  +import java.util.Enumeration;
> >>  +import java.util.List;
> >>  +import java.util.logging.Logger;
> >>  +
> >>  +/**
> >>  + * Simple default implementation of the resource loader, which does
> only
> >>  support direct references to files.
> >>  + */
> >>  +@Priority(0)
> >>  +public class DefaultResourceLoader implements ResourceLoader {
> >>  +
> >>  +    private static final Logger LOG =
> >>  Logger.getLogger(DefaultResourceLoader.class.getName());
> >>  +
> >>  +    @Override
> >>  +    public List<Resource> getResources(ClassLoader classLoader,
> >>  Collection<String> expressions) {
> >>  +        List<Resource> resources = new ArrayList<>();
> >>  +        for (String expression : expressions) {
> >>  +            if (tryClassPath(classLoader, expression, resources) ||
> >>  tryFile(expression, resources) ||
> >>  +                    tryURL(expression, resources)) {
> >>  +                continue;
> >>  +            }
> >>  +            LOG.warning("Failed to resolve resource: " +
> > expression);
> >>  +        }
> >>  +        return resources;
> >>  +    }
> >>  +
> >>  +    private boolean tryClassPath(ClassLoader classLoader, String
> > expression,
> >>  List<Resource> resources) {
> >>  +        try {
> >>  +            Enumeration<URL> urls =
> > classLoader.getResources(expression);
> >>  +            while (urls.hasMoreElements()) {
> >>  +                URL url = urls.nextElement();
> >>  +                resources.add(new URLResource(url));
> >>  +            }
> >>  +            return !resources.isEmpty();
> >>  +        } catch (Exception e) {
> >>  +            LOG.finest(() -> "Failed to load resource from CP:
> > " +
> >>  expression);
> >>  +        }
> >>  +        return false;
> >>  +    }
> >>  +
> >>  +    private boolean tryFile(String expression, List<Resource>
> > resources)
> >>  {
> >>  +        try {
> >>  +            File file = new File(expression);
> >>  +            if (file.exists()) {
> >>  +                resources.add(new FileResource(file));
> >>  +                return true;
> >>  +            }
> >>  +        } catch (Exception e) {
> >>  +            LOG.finest(() -> "Failed to load resource from file:
> > "
> >>  + expression);
> >>  +        }
> >>  +        return false;
> >>  +    }
> >>  +
> >>  +    private boolean tryURL(String expression, List<Resource>
> > resources)
> >>  {
> >>  +        try {
> >>  +            URL url = new URL(expression);
> >>  +            resources.add(new URLResource(url));
> >>  +            return true;
> >>  +        } catch (Exception e) {
> >>  +            LOG.finest(() -> "Failed to load resource from file:
> > "
> >>  + expression);
> >>  +        }
> >>  +        return false;
> >>  +
> >>  +    }
> >>  +
> >>  +}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
> >>  new file mode 100644
> >>  index 0000000..e0096e5
> >>  --- /dev/null
> >>  +++
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
> >>  @@ -0,0 +1,162 @@
> >>  +/*
> >>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>  + * or more contributor license agreements.  See the NOTICE file
> >>  + * distributed with this work for additional information
> >>  + * regarding copyright ownership.  The ASF licenses this file
> >>  + * to you under the Apache License, Version 2.0 (the
> >>  + * "License"); you may not use this file except in compliance
> >>  + * with the License.  You may obtain a copy of the License at
> >>  + *
> >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>  + *
> >>  + * Unless required by applicable law or agreed to in writing,
> >>  + * software distributed under the License is distributed on an
> >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  + * KIND, either express or implied.  See the License for the
> >>  + * specific language governing permissions and limitations
> >>  + * under the License.
> >>  + */
> >>  +package org.apache.tamaya.core.internal.resource;
> >>  +
> >>  +import org.apache.tamaya.core.resources.Resource;
> >>  +
> >>  +import java.io.File;
> >>  +import java.io.FileInputStream;
> >>  +import java.io.IOException;
> >>  +import java.io.InputStream;
> >>  +import java.net.URI;
> >>  +import java.util.Objects;
> >>  +
> >>  +/**
> >>  + * Implementation of {@link
> > org.apache.tamaya.core.resources.Resource} to
> >>  be loaded from a file.
> >>  + * @see java.io.File
> >>  + */
> >>  +public class FileResource implements Resource {
> >>  +
> >>  +    private final File file;
> >>  +
> >>  +    /**
> >>  +     * Creates a new instance.
> >>  +     *
> >>  +     * @param file a File, not null.
> >>  +     */
> >>  +    public FileResource(File file) {
> >>  +        this.file = Objects.requireNonNull(file, "File must not be
> >>  null");
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Crreates a new instance.
> >>  +     *
> >>  +     * @param filePath a file path
> >>  +     */
> >>  +    public FileResource(String filePath) {
> >>  +        Objects.requireNonNull(filePath, "Path must not be
> > null");
> >>  +        this.file = new File(filePath);
> >>  +    }
> >>  +
> >>  +
> >>  +    /**
> >>  +     * Get the file path for this resource.
> >>  +     */
> >>  +    public final String getPath() {
> >>  +        return this.file.getPath();
> >>  +    }
> >>  +
> >>  +
> >>  +    /**
> >>  +     * This implementation returns whether the underlying file exists.
> >>  +     *
> >>  +     * @see java.io.File#exists()
> >>  +     */
> >>  +    @Override
> >>  +    public boolean exists() {
> >>  +        return this.file.exists();
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * This implementation checks whether the underlying file is
> marked as
> >
> >>  readable
> >>  +     * (and corresponds to an actual file with content, not to a
> > directory).
> >>  +     *
> >>  +     * @see java.io.File#canRead()
> >>  +     * @see java.io.File#isDirectory()
> >>  +     */
> >>  +    @Override
> >>  +    public boolean isAccessible() {
> >>  +        return (this.file.canRead() && !this.file.isDirectory());
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * This implementation opens a FileInputStream for the underlying
> > file.
> >>  +     *
> >>  +     * @see java.io.FileInputStream
> >>  +     */
> >>  +    @Override
> >>  +    public InputStream getInputStream() throws IOException {
> >>  +        return new FileInputStream(this.file);
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * This implementation returns a URI for the underlying file.
> >>  +     *
> >>  +     * @see java.io.File#toURI()
> >>  +     */
> >>  +    @Override
> >>  +    public URI toURI() throws IOException {
> >>  +        return this.file.toURI();
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Returns the underlying File's length.
> >>  +     */
> >>  +    @Override
> >>  +    public long length() throws IOException {
> >>  +        return this.file.length();
> >>  +    }
> >>  +
> >>  +    @Override
> >>  +    public long lastModified() throws IOException {
> >>  +        return file.lastModified();
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Returns the name of the current file.
> >>  +     *
> >>  +     * @see java.io.File#getName()
> >>  +     */
> >>  +    @Override
> >>  +    public String getName() {
> >>  +        return this.file.getName();
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Returns a description that includes the absolute
> >>  +     * path of the current file.
> >>  +     *
> >>  +     * @see java.io.File#getAbsolutePath()
> >>  +     */
> >>  +    @Override
> >>  +    public String toString() {
> >>  +        return "File [" + this.file.getAbsolutePath() +
> >>  "]";
> >>  +    }
> >>  +
> >>  +
> >>  +    // implementation current WritableResource
> >>  +
> >>  +    /**
> >>  +     * Compares the underlying Files.
> >>  +     */
> >>  +    @Override
> >>  +    public boolean equals(Object obj) {
> >>  +        return (obj == this ||
> >>  +                (obj instanceof FileResource &&
> >>  this.file.equals(((FileResource) obj).file)));
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Returns hash code current the underlying File reference.
> >>  +     */
> >>  +    @Override
> >>  +    public int hashCode() {
> >>  +        return this.file.hashCode();
> >>  +    }
> >>  +
> >>  +}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
> >
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
> >>  new file mode 100644
> >>  index 0000000..09510b4
> >>  --- /dev/null
> >>  +++
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
> >>  @@ -0,0 +1,117 @@
> >>  +/*
> >>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>  + * or more contributor license agreements.  See the NOTICE file
> >>  + * distributed with this work for additional information
> >>  + * regarding copyright ownership.  The ASF licenses this file
> >>  + * to you under the Apache License, Version 2.0 (the
> >>  + * "License"); you may not use this file except in compliance
> >>  + * with the License.  You may obtain a copy of the License at
> >>  + *
> >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>  + *
> >>  + * Unless required by applicable law or agreed to in writing,
> >>  + * software distributed under the License is distributed on an
> >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  + * KIND, either express or implied.  See the License for the
> >>  + * specific language governing permissions and limitations
> >>  + * under the License.
> >>  + */
> >>  +package org.apache.tamaya.core.internal.resource;
> >>  +
> >>  +import org.apache.tamaya.core.resources.Resource;
> >>  +
> >>  +import java.io.IOException;
> >>  +import java.io.InputStream;
> >>  +import java.net.URI;
> >>  +import java.util.Objects;
> >>  +
> >>  +/**
> >>  + * Simple Resource encapsulating an InputStream.
> >>  + */
> >>  +public class InputStreamResource implements Resource {
> >>  +
> >>  +    /** The InputStream. */
> >>  +    private final InputStream inputStream;
> >>  +    /** The read flag. */
> >>  +    private boolean read = false;
> >>  +    /** The name of the resource. */
> >>  +    private String name;
> >>  +
> >>  +
> >>  +    /**
> >>  +     * Create a new InputStreamResource.
> >>  +     *
> >>  +     * @param inputStream the InputStream to use
> >>  +     */
> >>  +    public InputStreamResource(InputStream inputStream) {
> >>  +        this(inputStream, "InputStream:");
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Create a new InputStreamResource.
> >>  +     *
> >>  +     * @param inputStream the InputStream to use
> >>  +     * @param name where the InputStream comes from
> >>  +     */
> >>  +    public InputStreamResource(InputStream inputStream, String name)
> > {
> >>  +        this.inputStream = Objects.requireNonNull(inputStream);
> >>  +        this.name = (name != null ? name : "InputStream");
> >>  +    }
> >>  +
> >>  +
> >>  +    /**
> >>  +     * This implementation always returns {@code true}.
> >>  +     */
> >>  +    @Override
> >>  +    public boolean exists() {
> >>  +        return true;
> >>  +    }
> >>  +
> >>  +    @Override
> >>  +    public URI toURI() throws IOException {
> >>  +        throw new IOException("URI not available.");
> >>  +    }
> >>  +
> >>  +    @Override
> >>  +    public long lastModified() throws IOException {
> >>  +        throw new IOException("lastModified not available.");
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Accesses the input stream. Hereby the input stream can only
> > accessed
> >>  once.
> >>  +     */
> >>  +    @Override
> >>  +    public InputStream getInputStream() throws IOException {
> >>  +        if (this.read) {
> >>  +            throw new IllegalStateException("InputStream can only be
> > read
> >>  once!");
> >>  +        }
> >>  +        this.read = true;
> >>  +        return this.inputStream;
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * This implementation returns the passed-in description, if any.
> >>  +     */
> >>  +    public String toString() {
> >>  +        return this.name != null ? this.name : super.toString();
> >>  +    }
> >>  +
> >>  +
> >>  +    /**
> >>  +     * Compares the underlying InputStream.
> >>  +     */
> >>  +    @Override
> >>  +    public boolean equals(Object obj) {
> >>  +        return (obj == this ||
> >>  +                (obj instanceof InputStreamResource &&
> >>  ((InputStreamResource) obj).inputStream.equals(this.inputStream)));
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * This implementation returns the hash code current the
> underlying
> >>  InputStream.
> >>  +     */
> >>  +    @Override
> >>  +    public int hashCode() {
> >>  +        return this.inputStream.hashCode();
> >>  +    }
> >>  +
> >>  +}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
> >>  new file mode 100644
> >>  index 0000000..4da6c53
> >>  --- /dev/null
> >>  +++
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
> >>  @@ -0,0 +1,37 @@
> >>  +/*
> >>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>  + * or more contributor license agreements.  See the NOTICE file
> >>  + * distributed with this work for additional information
> >>  + * regarding copyright ownership.  The ASF licenses this file
> >>  + * to you under the Apache License, Version 2.0 (the
> >>  + * "License"); you may not use this file except in compliance
> >>  + * with the License.  You may obtain a copy of the License at
> >>  + *
> >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>  + *
> >>  + * Unless required by applicable law or agreed to in writing,
> >>  + * software distributed under the License is distributed on an
> >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  + * KIND, either express or implied.  See the License for the
> >>  + * specific language governing permissions and limitations
> >>  + * under the License.
> >>  + */
> >>  +package org.apache.tamaya.core.resources;
> >>  +
> >>  +import java.io.IOException;
> >>  +import java.io.InputStream;
> >>  +
> >>  +/**
> >>  + * Simple interface for a component that provides data based on an
> > InputStream.
> >>  + */
> >>  +@FunctionalInterface
> >>  +public interface InputStreamSupplier {
> >>  +
> >>  +    /**
> >>  +     * Access the input stream.
> >>  +     * @return the input stream for use.
> >>  +     * @throws IOException i the input stream could not be obtained.
> >>  +     */
> >>  +    InputStream getInputStream() throws IOException;
> >>  +
> >>  +}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> > a/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
> >>  b/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
> >>  new file mode 100644
> >>  index 0000000..31c679d
> >>  --- /dev/null
> >>  +++ b/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
> >>  @@ -0,0 +1,115 @@
> >>  +/*
> >>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>  + * or more contributor license agreements.  See the NOTICE file
> >>  + * distributed with this work for additional information
> >>  + * regarding copyright ownership.  The ASF licenses this file
> >>  + * to you under the Apache License, Version 2.0 (the
> >>  + * "License"); you may not use this file except in compliance
> >>  + * with the License.  You may obtain a copy of the License at
> >>  + *
> >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>  + *
> >>  + * Unless required by applicable law or agreed to in writing,
> >>  + * software distributed under the License is distributed on an
> >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  + * KIND, either express or implied.  See the License for the
> >>  + * specific language governing permissions and limitations
> >>  + * under the License.
> >>  + */
> >>  +package org.apache.tamaya.core.resources;
> >>  +
> >>  +import java.io.File;
> >>  +import java.io.IOException;
> >>  +import java.io.InputStream;
> >>  +import java.net.URI;
> >>  +import java.net.URL;
> >>  +import java.util.Objects;
> >>  +
> >>  +/**
> >>  + * Interface for an abstract resource. The effective resource
> > implementation
> >>  can be completely arbitrary.
> >>  + * By default files, classpath resources and URLs are supported, but
> > alternate
> >>  implementations are possible.
> >>  + *
> >>  + * @see #getInputStream()
> >>  + * @see #toURI()
> >>  + */
> >>  +public interface Resource extends InputStreamSupplier {
> >>  +
> >>  +    /**
> >>  +     * Return whether this resource actually exists. Depending on the
> > resource
> >>  this can delegate to
> >>  +     * {@link java.io.File#exists()} or whatever may be appropriate
> > to
> >>  check accessibility of the resource.
> >>  +     */
> >>  +    default boolean exists() {
> >>  +        // Try to open a file first, if that fails try to open the
> > stream...
> >>  +        try {
> >>  +            return new File(toURI()).exists();
> >>  +        } catch (IOException ex) {
> >>  +            // Fallback
> >>  +            try {
> >>  +                InputStream is = getInputStream();
> >>  +                is.close();
> >>  +                return true;
> >>  +            } catch (Exception e) {
> >>  +                // ignore, just return false for non existing
> >>  +                return false;
> >>  +            }
> >>  +        }
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Checks whether the resource is accessible, meaning {@link
> >>  #getInputStream()} should return a InputStream for reading the
> >>  +     * resource's content.
> >>  +     *
> >>  +     * @see #getInputStream()
> >>  +     */
> >>  +    default boolean isAccessible() {
> >>  +        return true;
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Returns the resource as an URI.
> >>  +     *
> >>  +     * @throws IOException if the resource cannot be resolved as URI.
> >>  +     */
> >>  +    URI toURI() throws IOException;
> >>  +
> >>  +    /**
> >>  +     * Determines the length for this resource.
> >>  +     *
> >>  +     * @throws IOException if the resource is not readable.
> >>  +     */
> >>  +    default long length() throws IOException {
> >>  +        try(InputStream is = this.getInputStream();) {
> >>  +            Objects.requireNonNull(is, "resource not
> > available");
> >>  +            long length = 0;
> >>  +            byte[] buf = new byte[256];
> >>  +            int bytesRead;
> >>  +            while ((bytesRead = is.read(buf)) > 0) {
> >>  +                length += bytesRead;
> >>  +            }
> >>  +            return length;
> >>  +        }
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Determine the last-modified timestamp for a resource, as UTC ms
> >>  timestamp
> >>  +     *
> >>  +     * @throws IOException if the resource is not accessible.
> >>  +     */
> >>  +    default long lastModified() throws IOException{
> >>  +        return new File(toURI()).lastModified();
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Get a name for the resource. The name should be identifying the
> > resource
> >>  and also
> >>  +     * never change, so it must be eligible for hashcode/equals
> >>  implementations.
> >>  +     */
> >>  +    default String getName() {
> >>  +        try {
> >>  +            return toURI().toString();
> >>  +        } catch (Exception e) {
> >>  +            return toString();
> >>  +        }
> >>  +    }
> >>  +
> >>  +
> >>  +}
> >>  \ No newline at end of file
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> a/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
> >>
> b/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
> >>  new file mode 100644
> >>  index 0000000..5aff10a
> >>  --- /dev/null
> >>  +++
> > b/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
> >>  @@ -0,0 +1,91 @@
> >>  +/*
> >>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>  + * or more contributor license agreements.  See the NOTICE file
> >>  + * distributed with this work for additional information
> >>  + * regarding copyright ownership.  The ASF licenses this file
> >>  + * to you under the Apache License, Version 2.0 (the
> >>  + * "License"); you may not use this file except in compliance
> >>  + * with the License.  You may obtain a copy of the License at
> >>  + *
> >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>  + *
> >>  + * Unless required by applicable law or agreed to in writing,
> >>  + * software distributed under the License is distributed on an
> >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  + * KIND, either express or implied.  See the License for the
> >>  + * specific language governing permissions and limitations
> >>  + * under the License.
> >>  + */
> >>  +package org.apache.tamaya.core.resources;
> >>  +
> >>  +import java.util.Arrays;
> >>  +import java.util.Collection;
> >>  +import java.util.List;
> >>  +
> >>  +/**
> >>  + * Interface to be implemented by modules. By default only direct
> > file/resource
> >>  resolution is supported, whereas
> >>  + * extension modules may add functionality to perform ant styled
> pattern
> >>  resolution of resources.
> >>  + */
> >>  +public interface ResourceLoader {
> >>  +
> >>  +    /**
> >>  +     * Resolves resource expressions to a list of {@link
> >>  org.apache.tamaya.core.resources.Resource}s. Hereby
> >>  +     * the ordering of resources matches the input of the resolved
> > expressions.
> >>  Nevertheless be aware that
> >>  +     * there is no determined ordering of resources located within a
> >>  classloader.
> >>  +     *
> >>  +     * @param expressions the expressions to be resolved, not empty.
> >>  +     * @return the corresponding collection of current {@link
> >>  org.apache.tamaya.core.resources.Resource}s found, never
> >>  +     * null.
> >>  +     * .
> >>  +     */
> >>  +    default Collection<Resource>
> > getResources(Collection<String>
> >>  expressions) {
> >>  +        ClassLoader cl =
> Thread.currentThread().getContextClassLoader();
> >>  +        if (cl == null) {
> >>  +            cl = getClass().getClassLoader();
> >>  +        }
> >>  +        return getResources(cl, expressions);
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Resolves resource expressions to a list of {@link
> >>  org.apache.tamaya.core.resources.Resource}s. Hereby
> >>  +     * the ordering of resources matches the input of the resolved
> > expressions.
> >>  Nevertheless be aware that
> >>  +     * there is no determined ordering of resources located within a
> >>  classloader.
> >>  +     *
> >>  +     * @param expressions the expressions to be resolved, not empty.
> >>  +     * @return the corresponding collection of current {@link
> >>  org.apache.tamaya.core.resources.Resource}s found, never
> >>  +     * null.
> >>  +     * .
> >>  +     */
> >>  +    default Collection<Resource> getResources(String... expressions)
> >
> >>  {
> >>  +        return getResources(Arrays.asList(expressions));
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Resolves resource expressions to a list of {@link
> >>  org.apache.tamaya.core.resources.Resource}s, considerubg
> >>  +     * the given classloader for classloader dependent resources.
> Hereby
> >>  +     * the ordering of resources matches the input of the resolved
> > expressions.
> >>  Nevertheless be aware that
> >>  +     * there is no determined ordering of resources located within a
> >>  classloader.
> >>  +     *
> >>  +     * @param expressions the expressions to be resolved, not empty.
> >>  +     * @return the corresponding collection of current {@link
> >>  org.apache.tamaya.core.resources.Resource}s found, never
> >>  +     * null.
> >>  +     * .
> >>  +     */
> >>  +    default Collection<Resource> getResources(ClassLoader
> > classLoader,
> >>  String... expressions){
> >>  +        return getResources(classLoader, Arrays.asList(expressions));
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Resolves resource expressions to a list of {@link
> >>  org.apache.tamaya.core.resources.Resource}s, considerubg
> >>  +     * the given classloader for classloader dependent resources.
> Hereby
> >>  +     * the ordering of resources matches the input of the resolved
> > expressions.
> >>  Nevertheless be aware that
> >>  +     * there is no determined ordering of resources located within a
> >>  classloader.
> >>  +     *
> >>  +     * @param expressions the expressions to be resolved, not empty.
> >>  +     * @return the corresponding collection of current {@link
> >>  org.apache.tamaya.core.resources.Resource}s found, never
> >>  +     * null.
> >>  +     * .
> >>  +     */
> >>  +    Collection<Resource> getResources(ClassLoader classLoader,
> >>  Collection<String> expressions);
> >>  +
> >>  +}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> > a/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> >>  b/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> >>  index be1eadb..9c7b894 100644
> >>  --- a/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> >>  +++ b/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> >>  @@ -41,6 +41,12 @@ public class ConfigurationTest {
> >>           assertEquals("Lukas",
> >>  Configuration.current().get("name3").get());  // oderridden
> > default
> >>           assertEquals("Sereina",
> >>  Configuration.current().get("name4").get()); // final only
> >>           assertEquals("Benjamin",
> >>  Configuration.current().get("name5").get()); // final only
> >>  +
> >>  +        System.out.println("name : " +
> >>  Configuration.current().get("name").get());
> >>  +        System.out.println("name2: " +
> >>  Configuration.current().get("name2").get());
> >>  +        System.out.println("name3: " +
> >>  Configuration.current().get("name3").get());
> >>  +        System.out.println("name4: " +
> >>  Configuration.current().get("name4").get());
> >>  +        System.out.println("name5: " +
> >>  Configuration.current().get("name5").get());
> >>       }
> >>
> >>
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
> >
> >>
> >
> b/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
> >>  deleted file mode 100644
> >>  index 51cc2dc..0000000
> >>  ---
> >>
> >
> a/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
> >>  +++ /dev/null
> >>  @@ -1,70 +0,0 @@
> >>  -/*
> >>  - * Licensed to the Apache Software Foundation (ASF) under one
> >>  - * or more contributor license agreements.  See the NOTICE file
> >>  - * distributed with this work for additional information
> >>  - * regarding copyright ownership.  The ASF licenses this file
> >>  - * to you under the Apache License, Version 2.0 (the
> >>  - * "License"); you may not use this file except in compliance
> >>  - * with the License.  You may obtain a copy of the License at
> >>  - *
> >>  - * http://www.apache.org/licenses/LICENSE-2.0
> >>  - *
> >>  - * Unless required by applicable law or agreed to in writing,
> >>  - * software distributed under the License is distributed on an
> >>  - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  - * KIND, either express or implied.  See the License for the
> >>  - * specific language governing permissions and limitations
> >>  - * under the License.
> >>  - */
> >>  -package org.apache.tamaya.core.test.propertysource;
> >>  -
> >>  -import org.apache.tamaya.core.propertysource.DefaultOrdinal;
> >>  -import
> org.apache.tamaya.core.propertysource.EnvironmentPropertySource;
> >>  -import org.junit.Assert;
> >>  -import org.junit.Test;
> >>  -
> >>  -import java.util.Map;
> >>  -import java.util.Optional;
> >>  -
> >>  -public class EnvironmentPropertySourceTest {
> >>  -
> >>  -    private EnvironmentPropertySource propertySource = new
> >>  EnvironmentPropertySource();
> >>  -
> >>  -
> >>  -    @Test
> >>  -    public void testGetOrdinal() {
> >>  -        Assert.assertEquals(DefaultOrdinal.ENVIRONMENT_PROPERTIES,
> >>  propertySource.getOrdinal());
> >>  -    }
> >>  -
> >>  -    @Test
> >>  -    public void testGet() {
> >>  -        String environmentPropertyToCheck =
> >>  System.getenv().keySet().iterator().next();
> >>  -
> >>  -        Optional<String> value =
> >>  propertySource.get(environmentPropertyToCheck);
> >>  -        Assert.assertTrue(value.isPresent());
> >>  -        Assert.assertEquals(System.getenv(environmentPropertyToCheck),
> >>  value.get());
> >>  -    }
> >>  -
> >>  -    @Test
> >>  -    public void testGetProperties() {
> >>  -        Map<String, String> environmentProperties = System.getenv();
> >>  -
> >>  -        Assert.assertEquals(environmentProperties.size(),
> >>  propertySource.getProperties().size());
> >>  -
> >>  -        for (Map.Entry<String, String> propertySourceEntry :
> >>  propertySource.getProperties().entrySet()) {
> >>  -            Assert.assertEquals("Entry values for key '" +
> >>  propertySourceEntry.getKey() + "' do not match",
> >>  -
> >>  environmentProperties.get(propertySourceEntry.getKey()),
> >>  propertySourceEntry.getValue());
> >>  -        }
> >>  -
> >>  -        // modification is not allowed
> >>  -        try {
> >>  -            propertySource.getProperties().put("add.new.keys",
> >>  "must throw exception");
> >>  -            Assert.fail(UnsupportedOperationException.class.getName()
> +
> > "
> >>  expected");
> >>  -        }
> >>  -        catch (UnsupportedOperationException e) {
> >>  -            // expected -> all is fine
> >>  -        }
> >>  -    }
> >>  -
> >>  -
> >>  -}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
> >
> >>
> >
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
> >>  new file mode 100644
> >>  index 0000000..5fa90b1
> >>  --- /dev/null
> >>  +++
> >>
> >
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
> >>  @@ -0,0 +1,32 @@
> >>  +/*
> >>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>  + * or more contributor license agreements.  See the NOTICE file
> >>  + * distributed with this work for additional information
> >>  + * regarding copyright ownership.  The ASF licenses this file
> >>  + * to you under the Apache License, Version 2.0 (the
> >>  + * "License"); you may not use this file except in compliance
> >>  + * with the License.  You may obtain a copy of the License at
> >>  + *
> >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>  + *
> >>  + * Unless required by applicable law or agreed to in writing,
> >>  + * software distributed under the License is distributed on an
> >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  + * KIND, either express or implied.  See the License for the
> >>  + * specific language governing permissions and limitations
> >>  + * under the License.
> >>  + */
> >>  +package org.apache.tamaya.core.testdata;
> >>  +
> >>  +import org.apache.tamaya.core.PathBasedPropertySourceProvider;
> >>  +import org.apache.tamaya.core.formats.PropertiesFormat;
> >>  +
> >>  +/**
> >>  + * Test provider reading properties from
> > classpath:cfg/defaults/**.properties.
> >>  + */
> >>  +public class TestPropertyDefaultSourceProvider extends
> >>  PathBasedPropertySourceProvider{
> >>  +
> >>  +    public TestPropertyDefaultSourceProvider() {
> >>  +        super("default-testdata-properties", new
> >>  PropertiesFormat(100), "classpath:cfg/defaults/**/*.properties");
> >>  +    }
> >>  +}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
> >>
> >
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
> >>  deleted file mode 100644
> >>  index d1314aa..0000000
> >>  ---
> >
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
> >>  +++ /dev/null
> >>  @@ -1,55 +0,0 @@
> >>  -/*
> >>  - * Licensed to the Apache Software Foundation (ASF) under one
> >>  - * or more contributor license agreements.  See the NOTICE file
> >>  - * distributed with this work for additional information
> >>  - * regarding copyright ownership.  The ASF licenses this file
> >>  - * to you under the Apache License, Version 2.0 (the
> >>  - * "License"); you may not use this file except in compliance
> >>  - * with the License.  You may obtain a copy of the License at
> >>  - *
> >>  - *  http://www.apache.org/licenses/LICENSE-2.0
> >>  - *
> >>  - * Unless required by applicable law or agreed to in writing,
> >>  - * software distributed under the License is distributed on an
> >>  - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  - * KIND, either express or implied.  See the License for the
> >>  - * specific language governing permissions and limitations
> >>  - * under the License.
> >>  - */
> >>  -package org.apache.tamaya.core.testdata;
> >>  -
> >>  -import java.util.HashMap;
> >>  -import java.util.Map;
> >>  -
> >>  -import org.apache.tamaya.core.propertysource.BasePropertySource;
> >>  -
> >>  -/**
> >>  - * Test provider reading properties from
> > classpath:cfg/final/**.properties.
> >>  - */
> >>  -public class TestPropertySource extends BasePropertySource {
> >>  -
> >>  -    private static final Map<String, String> VALUES;
> >>  -    static {
> >>  -        VALUES = new HashMap<String, String>();
> >>  -        VALUES.put("name", "Robin");
> >>  -        VALUES.put("name2", "Sabine");
> >>  -        VALUES.put("name3", "Lukas");
> >>  -        VALUES.put("name4", "Sereina");
> >>  -        VALUES.put("name5", "Benjamin");
> >>  -    }
> >>  -
> >>  -
> >>  -    public TestPropertySource() {
> >>  -        initialzeOrdinal(100);
> >>  -    }
> >>  -
> >>  -    @Override
> >>  -    public String getName() {
> >>  -        return "TestPropertySource";
> >>  -    }
> >>  -
> >>  -    @Override
> >>  -    public Map<String, String> getProperties() {
> >>  -        return VALUES;
> >>  -    }
> >>  -}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
> >
> >>
> >
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
> >>  new file mode 100644
> >>  index 0000000..beafbf9
> >>  --- /dev/null
> >>  +++
> >>
> >
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
> >>  @@ -0,0 +1,32 @@
> >>  +/*
> >>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>  + * or more contributor license agreements.  See the NOTICE file
> >>  + * distributed with this work for additional information
> >>  + * regarding copyright ownership.  The ASF licenses this file
> >>  + * to you under the Apache License, Version 2.0 (the
> >>  + * "License"); you may not use this file except in compliance
> >>  + * with the License.  You may obtain a copy of the License at
> >>  + *
> >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>  + *
> >>  + * Unless required by applicable law or agreed to in writing,
> >>  + * software distributed under the License is distributed on an
> >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  + * KIND, either express or implied.  See the License for the
> >>  + * specific language governing permissions and limitations
> >>  + * under the License.
> >>  + */
> >>  +package org.apache.tamaya.core.testdata;
> >>  +
> >>  +import org.apache.tamaya.core.PathBasedPropertySourceProvider;
> >>  +import org.apache.tamaya.core.formats.PropertiesFormat;
> >>  +
> >>  +/**
> >>  + * Test provider reading properties from
> > classpath:cfg/final/**.properties.
> >>  + */
> >>  +public class TestPropertySourceProvider extends
> >>  PathBasedPropertySourceProvider{
> >>  +
> >>  +    public TestPropertySourceProvider() {
> >>  +        super("final-testdata-properties", new
> > PropertiesFormat(200),
> >>  "classpath:cfg/final/**/*.properties");
> >>  +    }
> >>  +}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
> >
> >>
> >
> b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
> >>  deleted file mode 100644
> >>  index e6f7fad..0000000
> >>  ---
> >>
> >
> a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
> >>  +++ /dev/null
> >>  @@ -1,19 +0,0 @@
> >>  -#
> >>  -# Licensed to the Apache Software Foundation (ASF) under one
> >>  -# or more contributor license agreements.  See the NOTICE file
> >>  -# distributed with this work for additional information
> >>  -# regarding copyright ownership.  The ASF licenses this file
> >>  -# to you under the Apache License, Version 2.0 (the
> >>  -# "License"); you may not use this file except in compliance
> >>  -# with the License.  You may obtain a copy current the License at
> >>  -#
> >>  -#    http://www.apache.org/licenses/LICENSE-2.0
> >>  -#
> >>  -# Unless required by applicable law or agreed to in writing,
> >>  -# software distributed under the License is distributed on an
> >>  -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  -# KIND, either express or implied.  See the License for the
> >>  -# specific language governing permissions and limitations
> >>  -# under the License.
> >>  -#
> >>  -org.apache.tamaya.core.testdata.TestPropertySource
> >>  \ No newline at end of file
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
> >
> >>
> >
> b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
> >>  new file mode 100644
> >>  index 0000000..9db0ef4
> >>  --- /dev/null
> >>  +++
> >>
> >
> b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
> >>  @@ -0,0 +1,20 @@
> >>  +#
> >>  +# Licensed to the Apache Software Foundation (ASF) under one
> >>  +# or more contributor license agreements.  See the NOTICE file
> >>  +# distributed with this work for additional information
> >>  +# regarding copyright ownership.  The ASF licenses this file
> >>  +# to you under the Apache License, Version 2.0 (the
> >>  +# "License"); you may not use this file except in compliance
> >>  +# with the License.  You may obtain a copy current the License at
> >>  +#
> >>  +#    http://www.apache.org/licenses/LICENSE-2.0
> >>  +#
> >>  +# Unless required by applicable law or agreed to in writing,
> >>  +# software distributed under the License is distributed on an
> >>  +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  +# KIND, either express or implied.  See the License for the
> >>  +# specific language governing permissions and limitations
> >>  +# under the License.
> >>  +#
> >>  +org.apache.tamaya.core.testdata.TestPropertyDefaultSourceProvider
> >>  +org.apache.tamaya.core.testdata.TestPropertySourceProvider
> >>  \ No newline at end of file
> >>
> >
>

Re: [2/4] incubator-tamaya git commit: TAMAYA-42, 43, 44: Readded non Spring related parts. Simplified resource API. Readded other tests.

Posted by Anatole Tresch <at...@gmail.com>.
OK, that mail sounds better. That would be the way I expected it to be ;)
The answers are basically given in the other mail before...

2015-01-04 10:07 GMT+01:00 Mark Struberg <st...@yahoo.de>:

> I just became aware that maybe my VOTE was not clear enough.
>
> > 2.) Wouldn't it be easier to write the functionality ourselves
> > and be able to only implement the pieces we really need?
> > Currently all we need is ClassLoader.getResources() and be done.
>
> My aim was not to implement ALL the functionality originally taken from
> Spring but really only the things we need.
> And essentially the following:
>
> > Currently all we need is ClassLoader.getResources() and be done.
>
>
> Reading Properties from a resource is essentially a single line of code:
>
>
> java.util.Properties.load(ClassLoader.getResource(fileUrl).openStream());
>
> I don't yet get the benefit of the other code. Please explain.
>
>
> LieGrue,
> strub
>
>
>
>
>
> > On Sunday, 4 January 2015, 9:10, Mark Struberg <st...@yahoo.de>
> wrote:
> > > Anatole, WHY do we need all of this?
> >
> > It is NOWHERE used!
> >
> > Why do we add 21 classes which don't provide anything useful to the
> project?
> > There was even a VOTE that we should keep it simple and just do the
> things we
> > need.
> >
> > I really don't get it. Is our goal to create a lightweight but flexible
> > configuration system or is our goal to become big and fat?
> >
> >
> > Maybe it makes sense but if so then please explain it to us.
> >
> >
> > 1.) Why do we read in a specific format?
> >
> > All the system is handling String/String and only in the last step it
> *probably*
> > gets converted into a target Type. I fail to see the benefit. Please
> explain it
> > to us.
> >
> > 2.) Why do we need all the Resource implementations?
> >
> > Java provides Resource handling out of the box. Again: we don't need any
> > scripting. So why add some handling for dynamic scenarios which we do
> not have?
> > This is basically a copy of Spring.io. But we simply don't have anything
> > scripted in XML as Spring does. So why should we add it?
> >
> >
> > I'm really tired of seeing code all over the place which is not helpful
> for
> > the project. Please don't add things we don't really need.
> >
> >
> > LieGrue,
> > strub
> >
> >
> >
> >
> >
> >
> >
> >>  On Sunday, 4 January 2015, 2:52, "anatole@apache.org"
> > <an...@apache.org> wrote:
> >>  >T AMAYA-42,43,44: Readded non Spring related parts. Simplified
> resource
> > API.
> >>  Readded other tests.
> >>
> >>
> >>  Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo
> >>  Commit:
> > http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/cc237eb4
> >>  Tree:
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/cc237eb4
> >>  Diff:
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/cc237eb4
> >>
> >>  Branch: refs/heads/master
> >>  Commit: cc237eb41b7d0c660261f451f47bbf07b7770c46
> >>  Parents: 59a9e21
> >>  Author: anatole <an...@apache.org>
> >>  Authored: Sun Jan 4 02:17:56 2015 +0100
> >>  Committer: anatole <an...@apache.org>
> >>  Committed: Sun Jan 4 02:26:23 2015 +0100
> >>
> >>  ----------------------------------------------------------------------
> >>  .../org/apache/tamaya/spi/PropertyFilter.java   |  10 +-
> >>  .../core/PathBasedPropertySourceProvider.java   |  93 ++++++++++
> >>  .../core/ResourcePropertySourceProvider.java    | 102 +++++++++++
> >>  .../core/formats/ConfigurationFormat.java       |  53 ++++++
> >>  .../tamaya/core/formats/PropertiesFormat.java   | 114 ++++++++++++
> >>  .../core/formats/PropertiesXmlFormat.java       | 115 ++++++++++++
> >>  .../core/internal/DefaultConfiguration.java     |  27 ++-
> >>  .../internal/resource/ClassPathResource.java    | 178
> +++++++++++++++++++
> >>  .../resource/DefaultResourceLoader.java         |  93 ++++++++++
> >>  .../core/internal/resource/FileResource.java    | 162 +++++++++++++++++
> >>  .../internal/resource/InputStreamResource.java  | 117 ++++++++++++
> >>  .../core/resources/InputStreamSupplier.java     |  37 ++++
> >>  .../apache/tamaya/core/resources/Resource.java  | 115 ++++++++++++
> >>  .../tamaya/core/resources/ResourceLoader.java   |  91 ++++++++++
> >>  .../apache/tamaya/core/ConfigurationTest.java   |   6 +
> >>  .../EnvironmentPropertySourceTest.java          |  70 --------
> >>  .../TestPropertyDefaultSourceProvider.java      |  32 ++++
> >>  .../core/testdata/TestPropertySource.java       |  55 ------
> >>  .../testdata/TestPropertySourceProvider.java    |  32 ++++
> >>  .../org.apache.tamaya.spi.PropertySource        |  19 --
> >>  ...org.apache.tamaya.spi.PropertySourceProvider |  20 +++
> >>  21 files changed, 1388 insertions(+), 153 deletions(-)
> >>  ----------------------------------------------------------------------
> >>
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> a/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> >>  b/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> >>  index 7479008..c8626fc 100644
> >>  --- a/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> >>  +++ b/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> >>  @@ -19,7 +19,7 @@
> >>  package org.apache.tamaya.spi;
> >>
> >>
> >>  -import java.util.Map;
> >>  +import java.util.function.Function;
> >>
> >>  /**
> >>    * <p>Interface for filtering the current map of properties during
> > the
> >>  evaluation of the chain of PropertySources.
> >>  @@ -27,7 +27,7 @@ import java.util.Map;
> >>    * hereby is defined by the corresponding {@code @Priority}
> >>  annotation.</p>
> >>    * <p>Filters </p>
> >>    */
> >>  -public interface PropertyFilter<T>{
> >>  +public interface PropertyFilter{
> >>
> >>       /**
> >>        * <p>Maps the current {@code valueToBeFiltered} value to a
> > new
> >>  value. The resulting value will be used as the result
> >>  @@ -44,10 +44,10 @@ public interface PropertyFilter<T>{
> >>        *
> >>        * @param key the key accessed, not null.
> >>        * @param valueToBeFiltered the value to be filtered, not null.
> >>  -     * @param currentMap the current input property map, not null.
> Can be
> > used
> >>  for resolution of the filtered value
> >>  -     *                   or as datasource for additional
> meta-information,
> > such
> >>  as categories, sensitivity etc.
> >>  +     * @param propertyValueProvider accessor for reading additional
> (eg
> >>  metadata) properties to perform correct
> >>  +     *                              filtering, never null.
> >>        * @return the filtered map, never null.
> >>        */
> >>  -    String filterProperty(String key, String valueToBeFiltered,
> >>  Map<String,String> currentMap);
> >>  +    String filterProperty(String key, String valueToBeFiltered,
> >>  Function<String,String> propertyValueProvider);
> >>
> >>  }
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
> >
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
> >>  new file mode 100644
> >>  index 0000000..31dbf4b
> >>  --- /dev/null
> >>  +++
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
> >>  @@ -0,0 +1,93 @@
> >>  +/*
> >>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>  + * or more contributor license agreements.  See the NOTICE file
> >>  + * distributed with this work for additional information
> >>  + * regarding copyright ownership.  The ASF licenses this file
> >>  + * to you under the Apache License, Version 2.0 (the
> >>  + * "License"); you may not use this file except in compliance
> >>  + * with the License.  You may obtain a copy of the License at
> >>  + *
> >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>  + *
> >>  + * Unless required by applicable law or agreed to in writing,
> >>  + * software distributed under the License is distributed on an
> >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  + * KIND, either express or implied.  See the License for the
> >>  + * specific language governing permissions and limitations
> >>  + * under the License.
> >>  + */
> >>  +package org.apache.tamaya.core;
> >>  +
> >>  +import org.apache.tamaya.core.formats.ConfigurationFormat;
> >>  +import org.apache.tamaya.core.resources.Resource;
> >>  +import org.apache.tamaya.core.resources.ResourceLoader;
> >>  +import org.apache.tamaya.spi.PropertySource;
> >>  +import org.apache.tamaya.spi.PropertySourceProvider;
> >>  +import org.apache.tamaya.spi.ServiceContext;
> >>  +
> >>  +import java.util.ArrayList;
> >>  +import java.util.Arrays;
> >>  +import java.util.Collection;
> >>  +import java.util.List;
> >>  +import java.util.Objects;
> >>  +import java.util.logging.Level;
> >>  +import java.util.logging.Logger;
> >>  +
> >>  +/**
> >>  + * Implementation of a {@link PropertySourceProvider} that reads
> >>  configuration from some given resource paths
> >>  + * and using the given formats. The resource path are resolved using
> the
> >>  current
> >>  + * {@link org.apache.tamaya.core.resources.ResourceLoader} active.
> >>  + */
> >>  +public class PathBasedPropertySourceProvider implements
> > PropertySourceProvider
> >>  {
> >>  +    /** The logger used. */
> >>  +    private static final Logger LOG =
> >>  Logger.getLogger(PathBasedPropertySourceProvider.class.getName());
> >>  +    /** The property source base name, will be used for creating a
> useful
> > name
> >>  of the
> >>  +     * {@link org.apache.tamaya.spi.PropertySource} created. */
> >>  +    private String sourceName;
> >>  +    /** The config formats supported for the given location/resource
> > paths. */
> >>  +    private List<ConfigurationFormat> configFormats = new
> >>  ArrayList<>();
> >>  +    /** The paths to be evaluated. */
> >>  +    private List<String> paths = new ArrayList<>();
> >>  +
> >>  +    /**
> >>  +     * Creates a new instance.
> >>  +     * @param sourceName the base name of the configuration, used for
> > creating
> >>  PropertySource child names.
> >>  +     * @param formats the formats to be used, not null, not empty.
> >>  +     * @param paths the paths to be resolved, not null, not empty.
> >>  +     */
> >>  +    public PathBasedPropertySourceProvider(String sourceName,
> >>  List<ConfigurationFormat> formats, String... paths) {
> >>  +        this.sourceName = Objects.requireNonNull(sourceName);
> >>  +        this.configFormats.addAll(Objects.requireNonNull(formats));
> >>  +
> this.paths.addAll(Arrays.asList(Objects.requireNonNull(paths)));
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Creates a new instance.
> >>  +     * @param sourceName the base name of the configuration, used for
> > creating
> >>  PropertySource child names.
> >>  +     * @param format the format to be used.
> >>  +     * @param paths the paths to be resolved, not null, not empty.
> >>  +     */
> >>  +    public PathBasedPropertySourceProvider(String sourceName,
> >>  ConfigurationFormat format, String... paths) {
> >>  +        this.sourceName = Objects.requireNonNull(sourceName);
> >>  +        this.configFormats.add(Objects.requireNonNull(format));
> >>  +
> this.paths.addAll(Arrays.asList(Objects.requireNonNull(paths)));
> >>  +    }
> >>  +
> >>  +    @Override
> >>  +    public Collection<PropertySource> getPropertySources() {
> >>  +        List<PropertySource> propertySources = new
> > ArrayList<>();
> >>  +        paths.forEach((path) -> {
> >>  +            for (Resource res :
> >>
> >
> ServiceContext.getInstance().getService(ResourceLoader.class).get().getResources(path))
> >
> >>  {
> >>  +                try {
> >>  +                    for (ConfigurationFormat format : configFormats)
> > {
> >>  +
> >>  propertySources.addAll(format.readConfiguration(sourceName, res));
> >>  +                    }
> >>  +                } catch (Exception e) {
> >>  +                    LOG.log(Level.WARNING, "Failed to add resource
> > based
> >>  config: " + res.getName(), e);
> >>  +                }
> >>  +            }
> >>  +        });
> >>  +        return propertySources;
> >>  +    }
> >>  +
> >>  +}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
> >>  new file mode 100644
> >>  index 0000000..de6b578
> >>  --- /dev/null
> >>  +++
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
> >>  @@ -0,0 +1,102 @@
> >>  +/*
> >>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>  + * or more contributor license agreements.  See the NOTICE file
> >>  + * distributed with this work for additional information
> >>  + * regarding copyright ownership.  The ASF licenses this file
> >>  + * to you under the Apache License, Version 2.0 (the
> >>  + * "License"); you may not use this file except in compliance
> >>  + * with the License.  You may obtain a copy of the License at
> >>  + *
> >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>  + *
> >>  + * Unless required by applicable law or agreed to in writing,
> >>  + * software distributed under the License is distributed on an
> >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  + * KIND, either express or implied.  See the License for the
> >>  + * specific language governing permissions and limitations
> >>  + * under the License.
> >>  + */
> >>  +package org.apache.tamaya.core;
> >>  +
> >>  +import org.apache.tamaya.core.formats.ConfigurationFormat;
> >>  +import org.apache.tamaya.core.resources.Resource;
> >>  +import org.apache.tamaya.spi.PropertySource;
> >>  +import org.apache.tamaya.spi.PropertySourceProvider;
> >>  +
> >>  +import java.util.ArrayList;
> >>  +import java.util.Arrays;
> >>  +import java.util.Collection;
> >>  +import java.util.List;
> >>  +import java.util.Objects;
> >>  +import java.util.logging.Logger;
> >>  +
> >>  +/**
> >>  + * Implementation of a {@link
> >>  org.apache.tamaya.spi.PropertySourceProvider} that is based on a single
> > resource
> >>  + * and a number of formats.
> >>  + */
> >>  +public class ResourcePropertySourceProvider implements
> > PropertySourceProvider
> >>  {
> >>  +    /** The logger used. */
> >>  +    private static final Logger LOG =
> >>  Logger.getLogger(ResourcePropertySourceProvider.class.getName());
> >>  +    /** The supported formats. */
> >>  +    private List<ConfigurationFormat> formats = new
> > ArrayList<>();
> >>  +    /** The resource. */
> >>  +    private Resource resource;
> >>  +    /** The source name used for creating the PropertySource names. */
> >>  +    private String sourceName;
> >>  +
> >>  +    /**
> >>  +     * Creates a new instance.
> >>  +     * @param resource the {@link
> >>  org.apache.tamaya.core.resources.Resource}, not null.
> >>  +     * @param formats the supported formats, not empty.
> >>  +     */
> >>  +    public ResourcePropertySourceProvider(String sourceName, Resource
> > resource,
> >>  ConfigurationFormat... formats) {
> >>  +        this(sourceName, resource, Arrays.asList(formats));
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Creates a new instance.
> >>  +     * @param resource the {@link
> >>  org.apache.tamaya.core.resources.Resource}, not null.
> >>  +     * @param formats the supported formats, not empty.
> >>  +     */
> >>  +    public ResourcePropertySourceProvider(String sourceName, Resource
> > resource,
> >>  List<ConfigurationFormat> formats) {
> >>  +        this.resource = Objects.requireNonNull(resource);
> >>  +        this.sourceName = Objects.requireNonNull(sourceName);
> >>  +        if(formats.size()==0){
> >>  +            throw new IllegalArgumentException("Format
> > required.");
> >>  +        }
> >>  +        this.formats.addAll(formats);
> >>  +    }
> >>  +
> >>  +
> >>  +    /**
> >>  +     * Get the underlying resource.
> >>  +     *
> >>  +     * @return the underlying resource, never null.
> >>  +     */
> >>  +    public Resource getResource() {
> >>  +        return this.resource;
> >>  +    }
> >>  +
> >>  +
> >>  +    @Override
> >>  +    public String toString() {
> >>  +        return "ResourcePropertySourceProvider{" +
> >>  +                "resource=" + resource +
> >>  +                ", formats=+" + formats +
> >>  +                '}';
> >>  +    }
> >>  +
> >>  +    @Override
> >>  +    public Collection<PropertySource> getPropertySources() {
> >>  +        List<PropertySource> propertySources = new
> > ArrayList<>();
> >>  +        for (ConfigurationFormat format : formats) {
> >>  +            try {
> >>  +
> > propertySources.addAll(format.readConfiguration(sourceName,
> >>  resource));
> >>  +            } catch (Exception e) {
> >>  +                LOG.info(() -> "Format was not matching: " +
> >>  format + " for resource: " + resource.getName());
> >>  +            }
> >>  +        }
> >>  +        return propertySources;
> >>  +    }
> >>  +
> >>  +}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
> >>  new file mode 100644
> >>  index 0000000..5d289bb
> >>  --- /dev/null
> >>  +++
> >
> b/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
> >>  @@ -0,0 +1,53 @@
> >>  +/*
> >>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>  + * or more contributor license agreements.  See the NOTICE file
> >>  + * distributed with this work for additional information
> >>  + * regarding copyright ownership.  The ASF licenses this file
> >>  + * to you under the Apache License, Version 2.0 (the
> >>  + * "License"); you may not use this file except in compliance
> >>  + * with the License.  You may obtain a copy of the License at
> >>  + *
> >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>  + *
> >>  + * Unless required by applicable law or agreed to in writing,
> >>  + * software distributed under the License is distributed on an
> >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  + * KIND, either express or implied.  See the License for the
> >>  + * specific language governing permissions and limitations
> >>  + * under the License.
> >>  + */
> >>  +package org.apache.tamaya.core.formats;
> >>  +
> >>  +import org.apache.tamaya.core.resources.Resource;
> >>  +import org.apache.tamaya.spi.PropertySource;
> >>  +
> >>  +import java.io.IOException;
> >>  +import java.util.Collection;
> >>  +
> >>  +/**
> >>  + * Implementations current this class encapsulate the mechanism how to
> > read a
> >>  + * resource including interpreting the format correctly (e.g. xml vs.
> >>  + * properties). In most cases file only contains entries of the same
> > priority,
> >>  which would then
> >>  + * result in only one {@link PropertySource}. Complex file formats,
> >>  hoiwever, may contain entries
> >>  + * of different priorities. In this cases, each ordinal type found
> must be
> >
> >>  returned as a separate
> >>  + * {@link PropertySource} instance.
> >>  + */
> >>  +@FunctionalInterface
> >>  +public interface ConfigurationFormat {
> >>  +
> >>  +    /**
> >>  +     * Reads a list {@link org.apache.tamaya.spi.PropertySource}
> > instances
> >>  from a resource, using this format.
> >>  +     * If the configuration format only contains entries of one
> ordinal
> > type,
> >>  normally only one single
> >>  +     * instance of PropertySource is returned. Nevertheless custom
> formats
> > may
> >>  contain different sections or parts,
> >>  +     * where each part maps to a different target rdinal (eg defaults,
> > domain
> >>  config and app config). In the
> >>  +     * ladder case multiple PropertySources can be returned, each one
> with
> > its
> >>  own ordinal and the corresponding
> >>  +     * entries.
> >>  +     *
> >>  +     * @param sourceName name to be used for constructing a useful
> name
> > for the
> >>  created
> >>  +     *                   {@link org.apache.tamaya.spi.PropertySource}
> >
> >>  instances.
> >>  +     * @param resource   the configuration resource, not null
> >>  +     * @return the corresponding {@link
> >>  org.apache.tamaya.spi.PropertySource} instances, never {@code null}.
> >>  +     */
> >>  +    Collection<PropertySource> readConfiguration(String sourceName,
> >>  Resource resource) throws IOException;
> >>  +
> >>  +}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> a/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
> >>
> b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
> >>  new file mode 100644
> >>  index 0000000..3584f8e
> >>  --- /dev/null
> >>  +++
> > b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
> >>  @@ -0,0 +1,114 @@
> >>  +/*
> >>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>  + * or more contributor license agreements.  See the NOTICE file
> >>  + * distributed with this work for additional information
> >>  + * regarding copyright ownership.  The ASF licenses this file
> >>  + * to you under the Apache License, Version 2.0 (the
> >>  + * "License"); you may not use this file except in compliance
> >>  + * with the License.  You may obtain a copy of the License at
> >>  + *
> >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>  + *
> >>  + * Unless required by applicable law or agreed to in writing,
> >>  + * software distributed under the License is distributed on an
> >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  + * KIND, either express or implied.  See the License for the
> >>  + * specific language governing permissions and limitations
> >>  + * under the License.
> >>  + */
> >>  +package org.apache.tamaya.core.formats;
> >>  +
> >>  +import org.apache.tamaya.core.resources.Resource;
> >>  +import org.apache.tamaya.spi.PropertySource;
> >>  +
> >>  +import java.io.InputStream;
> >>  +import java.util.ArrayList;
> >>  +import java.util.Collection;
> >>  +import java.util.Collections;
> >>  +import java.util.List;
> >>  +import java.util.Map;
> >>  +import java.util.Optional;
> >>  +import java.util.Properties;
> >>  +import java.util.logging.Level;
> >>  +import java.util.logging.Logger;
> >>  +
> >>  +/**
> >>  + * Implementation of a {@link
> >>  org.apache.tamaya.core.formats.ConfigurationFormat} for -properties
> files.
> >>  + *
> >>  + * @see java.util.Properties#load(java.io.InputStream)
> >>  + */
> >>  +public class PropertiesFormat implements ConfigurationFormat {
> >>  +    /**
> >>  +     * The logger.
> >>  +     */
> >>  +    private final static Logger LOG =
> >>  Logger.getLogger(PropertiesFormat.class.getName());
> >>  +
> >>  +    /**
> >>  +     * The target ordinal.
> >>  +     */
> >>  +    private int ordinal;
> >>  +
> >>  +    /**
> >>  +     * Creates a new format instance, hereby producing entries with
> the
> > given
> >>  ordinal, if not overridden by the
> >>  +     * configuration itself.
> >>  +     * TODO document and implement override feature
> >>  +     * @param ordinal the target ordinal.
> >>  +     */
> >>  +    public PropertiesFormat(int ordinal) {
> >>  +        this.ordinal = ordinal;
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Get the target ordinal, produced by this format.
> >>  +     *
> >>  +     * @return the target ordinal
> >>  +     */
> >>  +    public int getOrdinal() {
> >>  +        return ordinal;
> >>  +    }
> >>  +
> >>  +    @SuppressWarnings("unchecked")
> >>  +    @Override
> >>  +    public Collection<PropertySource> readConfiguration(String
> > baseName,
> >>  Resource resource) {
> >>  +        final String sourceName =
> >>  (baseName==null?"Properties:":baseName) + resource.getName();
> >>  +        if (resource.exists()) {
> >>  +            List<PropertySource> propertySources = new
> >>  ArrayList<>();
> >>  +            try (InputStream is = resource.getInputStream()) {
> >>  +                final Properties p = new Properties();
> >>  +                p.load(is);
> >>  +                propertySources.add(new PropertySource() {
> >>  +                    @Override
> >>  +                    public int getOrdinal() {
> >>  +                        return ordinal;
> >>  +                    }
> >>  +
> >>  +                    @Override
> >>  +                    public String getName() {
> >>  +                        return sourceName;
> >>  +                    }
> >>  +
> >>  +                    @Override
> >>  +                    public Optional<String> get(String key) {
> >>  +                        return
> Optional.ofNullable(p.getProperty(key));
> >>  +                    }
> >>  +
> >>  +                    @Override
> >>  +                    public Map<String, String> getProperties()
> > {
> >>  +                        return Map.class.cast(p);
> >>  +                    }
> >>  +                });
> >>  +                return propertySources;
> >>  +            } catch (Exception e) {
> >>  +                LOG.log(Level.FINEST, e, () -> "Failed to read
> > config
> >>  from resource: " + resource);
> >>  +            }
> >>  +        }
> >>  +        return Collections.emptyList();
> >>  +    }
> >>  +
> >>  +    @Override
> >>  +    public String toString() {
> >>  +        return "PropertiesFormat{" +
> >>  +                "ordinal=" + ordinal +
> >>  +                '}';
> >>  +    }
> >>  +}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
> >>  new file mode 100644
> >>  index 0000000..3f77810
> >>  --- /dev/null
> >>  +++
> >
> b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
> >>  @@ -0,0 +1,115 @@
> >>  +/*
> >>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>  + * or more contributor license agreements.  See the NOTICE file
> >>  + * distributed with this work for additional information
> >>  + * regarding copyright ownership.  The ASF licenses this file
> >>  + * to you under the Apache License, Version 2.0 (the
> >>  + * "License"); you may not use this file except in compliance
> >>  + * with the License.  You may obtain a copy of the License at
> >>  + *
> >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>  + *
> >>  + * Unless required by applicable law or agreed to in writing,
> >>  + * software distributed under the License is distributed on an
> >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  + * KIND, either express or implied.  See the License for the
> >>  + * specific language governing permissions and limitations
> >>  + * under the License.
> >>  + */
> >>  +package org.apache.tamaya.core.formats;
> >>  +
> >>  +import org.apache.tamaya.core.resources.Resource;
> >>  +import org.apache.tamaya.spi.PropertySource;
> >>  +
> >>  +import java.io.InputStream;
> >>  +import java.util.ArrayList;
> >>  +import java.util.Collection;
> >>  +import java.util.Collections;
> >>  +import java.util.List;
> >>  +import java.util.Map;
> >>  +import java.util.Optional;
> >>  +import java.util.Properties;
> >>  +import java.util.logging.Level;
> >>  +import java.util.logging.Logger;
> >>  +
> >>  +/**
> >>  + * Implementation of a {@link
> >>  org.apache.tamaya.core.formats.ConfigurationFormat} for xml property
> >>  + * files.
> >>  + *
> >>  + * @see java.util.Properties#loadFromXML(java.io.InputStream)
> >>  + */
> >>  +public class PropertiesXmlFormat implements ConfigurationFormat {
> >>  +    /**
> >>  +     * The logger.
> >>  +     */
> >>  +    private final static Logger LOG =
> >>  Logger.getLogger(PropertiesXmlFormat.class.getName());
> >>  +
> >>  +    /**
> >>  +     * The target ordinal.
> >>  +     */
> >>  +    private int ordinal;
> >>  +
> >>  +    /**
> >>  +     * Creates a new format instance, producing entries for the given
> > ordinal,
> >>  if not overridden by a
> >>  +     * config entry itself.
> >>  +     * TODO document and implement override feature
> >>  +     * @param ordinal the target ordinal.
> >>  +     */
> >>  +    public PropertiesXmlFormat(int ordinal) {
> >>  +        this.ordinal = ordinal;
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Get the target ordinal, produced by this format.
> >>  +     *
> >>  +     * @return the target ordinal
> >>  +     */
> >>  +    public int getOrdinal() {
> >>  +        return ordinal;
> >>  +    }
> >>  +
> >>  +    @SuppressWarnings("unchecked")
> >>  +    @Override
> >>  +    public Collection<PropertySource> readConfiguration(String
> > baseName,
> >>  Resource resource) {
> >>  +        if (resource.exists()) {
> >>  +            final String sourceName =
> >>  (baseName==null?"Properties:":baseName) + resource.getName();
> >>  +            List<PropertySource> propertySources = new
> >>  ArrayList<>();
> >>  +            try (InputStream is = resource.getInputStream()) {
> >>  +                final Properties p = new Properties();
> >>  +                p.loadFromXML(is);
> >>  +                propertySources.add(new PropertySource() {
> >>  +                    @Override
> >>  +                    public int getOrdinal() {
> >>  +                        return ordinal;
> >>  +                    }
> >>  +
> >>  +                    @Override
> >>  +                    public String getName() {
> >>  +                        return sourceName;
> >>  +                    }
> >>  +
> >>  +                    @Override
> >>  +                    public Optional<String> get(String key) {
> >>  +                        return
> Optional.ofNullable(p.getProperty(key));
> >>  +                    }
> >>  +
> >>  +                    @Override
> >>  +                    public Map<String, String> getProperties()
> > {
> >>  +                        return Map.class.cast(p);
> >>  +                    }
> >>  +                });
> >>  +                return propertySources;
> >>  +            } catch (Exception e) {
> >>  +                LOG.log(Level.FINEST, e, () -> "Failed to read
> > config
> >>  from resource: " + resource);
> >>  +            }
> >>  +        }
> >>  +        return Collections.emptyList();
> >>  +    }
> >>  +
> >>  +    @Override
> >>  +    public String toString() {
> >>  +        return "PropertiesXmlFormat{" +
> >>  +                "ordinal=" + ordinal +
> >>  +                '}';
> >>  +    }
> >>  +}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> >>  index 0a39b7d..3769e27 100644
> >>  ---
> >>
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> >>  +++
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> >>  @@ -22,6 +22,7 @@ import org.apache.tamaya.ConfigException;
> >>  import org.apache.tamaya.Configuration;
> >>  import org.apache.tamaya.spi.ConfigurationContext;
> >>  import org.apache.tamaya.spi.PropertyConverter;
> >>  +import org.apache.tamaya.spi.PropertyFilter;
> >>  import org.apache.tamaya.spi.PropertySource;
> >>  import org.apache.tamaya.spi.ServiceContext;
> >>
> >>  @@ -33,6 +34,7 @@ import java.util.Map;
> >>  import java.util.Optional;
> >>  import java.util.logging.Level;
> >>  import java.util.logging.Logger;
> >>  +import java.util.stream.Collectors;
> >>
> >>  /**
> >>    * Implementation of the Configuration API. This class uses the
> current
> >>  {@link ConfigurationContext} to evaluate the
> >>  @@ -56,13 +58,21 @@ public class DefaultConfiguration implements
> > Configuration
> >>  {
> >>       @Override
> >>       public Optional<String> get(String key) {
> >>           List<PropertySource> propertySources =
> >>
> >
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertySources();
> >>  +        String unfilteredValue = null;
> >>           for (PropertySource propertySource : propertySources) {
> >>               Optional<String> value = propertySource.get(key);
> >>               if (value.isPresent()) {
> >>  -                return value;
> >>  +                unfilteredValue = value.get();
> >>  +                break;
> >>               }
> >>           }
> >>  -        return Optional.empty();
> >>  +        // Apply filters to values, prevent values filtered to null!
> >>  +        for(PropertyFilter filter:
> >>  +
> >>
> >
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyFilters()){
> >>  +            unfilteredValue = filter.filterProperty(key,
> unfilteredValue,
> >>  +                    (String k) ->
> > key.equals(k)?null:get(k).orElse(null));
> >>  +        }
> >>  +        return Optional.ofNullable(unfilteredValue);
> >>       }
> >>
> >>       @Override
> >>  @@ -83,7 +93,15 @@ public class DefaultConfiguration implements
> > Configuration
> >>  {
> >>                   LOG.log(Level.SEVERE, "Error adding properties from
> >>  PropertySource: " + propertySource +", ignoring
> > PropertySource.",
> >>  e);
> >>               }
> >>           }
> >>  -        return result;
> >>  +        // Apply filters to values, prevent values filtered to null!
> >>  +        for(PropertyFilter filter:
> >>  +
> >>
> >
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyFilters()){
> >>  +            result.replaceAll((k,v) -> filter.filterProperty(k, v,
> >>  +                    (String k2) ->
> > k2.equals(k)?null:get(k2).orElse(null)));
> >>  +        }
> >>  +        // Remove null values
> >>  +        return result.entrySet().parallelStream().filter((e) ->
> >>  e.getValue()!=null).collect(
> >>  +                Collectors.toMap((e) -> e.getKey(), (e) ->
> >>  e.getValue()));
> >>       }
> >>
> >>       /**
> >>  @@ -101,7 +119,8 @@ public class DefaultConfiguration implements
> > Configuration
> >>  {
> >>       public <T> Optional<T> get(String key, Class<T>
> > type)
> >>  {
> >>           Optional<String> value = get(key);
> >>           if (value.isPresent()) {
> >>  -            List<PropertyConverter<T>> converters =
> >>
> >
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyConverters(type);
> >>  +            List<PropertyConverter<T>> converters =
> >>  ServiceContext.getInstance().getService(ConfigurationContext.class)
> >>  +                    .get().getPropertyConverters(type);
> >>               for (PropertyConverter<T> converter : converters) {
> >>                   try {
> >>                       T t = converter.convert(value.get());
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
> >
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
> >>  new file mode 100644
> >>  index 0000000..21806cd
> >>  --- /dev/null
> >>  +++
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
> >>  @@ -0,0 +1,178 @@
> >>  +/*
> >>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>  + * or more contributor license agreements.  See the NOTICE file
> >>  + * distributed with this work for additional information
> >>  + * regarding copyright ownership.  The ASF licenses this file
> >>  + * to you under the Apache License, Version 2.0 (the
> >>  + * "License"); you may not use this file except in compliance
> >>  + * with the License.  You may obtain a copy of the License at
> >>  + *
> >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>  + *
> >>  + * Unless required by applicable law or agreed to in writing,
> >>  + * software distributed under the License is distributed on an
> >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  + * KIND, either express or implied.  See the License for the
> >>  + * specific language governing permissions and limitations
> >>  + * under the License.
> >>  + */
> >>  +package org.apache.tamaya.core.internal.resource;
> >>  +
> >>  +import org.apache.tamaya.core.resources.Resource;
> >>  +
> >>  +import java.io.IOException;
> >>  +import java.io.InputStream;
> >>  +import java.net.URI;
> >>  +import java.net.URISyntaxException;
> >>  +import java.net.URL;
> >>  +import java.util.Objects;
> >>  +
> >>  +/**
> >>  + * Implementation of {@link Resource} to be loaded from the
> > classpath.
> >>  + */
> >>  +public class ClassPathResource implements Resource {
> >>  +
> >>  +    private final String path;
> >>  +
> >>  +    private ClassLoader classLoader;
> >>  +
> >>  +
> >>  +    /**
> >>  +     * Create a new resource using the current context class loader.
> >>  +     *
> >>  +     * @param path the resource path, not null
> >>  +     * @see java.lang.ClassLoader#getResourceAsStream(String)
> >>  +     */
> >>  +    public ClassPathResource(String path) {
> >>  +        this(path, (ClassLoader) null);
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Create a new resource using the given class loader.
> >>  +     *
> >>  +     * @param path        the resource path, not null
> >>  +     * @param classLoader the class loader to load the resource with,
> >>  +     *                    or {@code null} for the current context
> > class
> >>  loader
> >>  +     * @see ClassLoader#getResourceAsStream(String)
> >>  +     */
> >>  +    public ClassPathResource(String path, ClassLoader classLoader) {
> >>  +        Objects.requireNonNull(path, "Path null");
> >>  +        if (path.startsWith("/")) {
> >>  +            path = path.substring(1);
> >>  +        }
> >>  +        this.path = path.trim();
> >>  +        if(classLoader==null){
> >>  +            classLoader =
> Thread.currentThread().getContextClassLoader();
> >>  +        }
> >>  +        if(classLoader==null){
> >>  +            classLoader = getClass().getClassLoader();
> >>  +        }
> >>  +        this.classLoader = classLoader;
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * @return the path for this resource.
> >>  +     */
> >>  +    public final String getPath() {
> >>  +        return this.path;
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * @return the ClassLoader that this resource will be accessed
> from.
> >>  +     */
> >>  +    public final ClassLoader getClassLoader() {
> >>  +        return this.classLoader;
> >>  +    }
> >>  +
> >>  +
> >>  +    /**
> >>  +     * Checks if the given resource is resolvable from the configured
> >>  classloader.
> >>  +     *
> >>  +     * @see java.lang.ClassLoader#getResource(String)
> >>  +     */
> >>  +    @Override
> >>  +    public boolean exists() {
> >>  +        return (resolveURL() != null);
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Resolves a URL for the underlying class path resource.
> >>  +     *
> >>  +     * @return the resolved URL, or {@code null}
> >>  +     */
> >>  +    protected URL resolveURL() {
> >>  +        return this.classLoader.getResource(this.path);
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * This implementation opens an InputStream for the given class
> path
> >>  resource.
> >>  +     *
> >>  +     * @see java.lang.ClassLoader#getResourceAsStream(String)
> >>  +     * @see java.lang.Class#getResourceAsStream(String)
> >>  +     */
> >>  +    @Override
> >>  +    public InputStream getInputStream() throws IOException {
> >>  +        InputStream is =
> this.classLoader.getResourceAsStream(this.path);
> >>  +        if (is == null) {
> >>  +            throw new IOException(getName() + " does not
> > exist");
> >>  +        }
> >>  +        return is;
> >>  +    }
> >>  +
> >>  +    @Override
> >>  +    public URI toURI() throws IOException {
> >>  +        try {
> >>  +            return resolveURL().toURI();
> >>  +        } catch (URISyntaxException e) {
> >>  +            throw new IOException(e);
> >>  +        }
> >>  +    }
> >>  +
> >>  +    @Override
> >>  +    public long lastModified() throws IOException {
> >>  +        return 0;
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * This implementation returns the name current the file that this
> > class
> >>  path
> >>  +     * resource refers to.
> >>  +     */
> >>  +    @Override
> >>  +    public String getName() {
> >>  +        return "classpath:"+path;
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * This implementation returns a description that includes the
> class
> > path
> >>  location.
> >>  +     */
> >>  +    @Override
> >>  +    public String toString() {
> >>  +        return "ClassPathResource[" + path + ']';
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * This implementation compares the underlying class path
> locations.
> >>  +     */
> >>  +    @Override
> >>  +    public boolean equals(Object obj) {
> >>  +        if (obj == this) {
> >>  +            return true;
> >>  +        }
> >>  +        if (obj instanceof ClassPathResource) {
> >>  +            ClassPathResource otherRes = (ClassPathResource) obj;
> >>  +            return (this.path.equals(otherRes.path) &&
> >>  +                    Objects.equals(this.classLoader,
> > otherRes.classLoader));
> >>  +        }
> >>  +        return false;
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * This implementation returns the hash code current the
> underlying
> >>  +     * class path location.
> >>  +     */
> >>  +    @Override
> >>  +    public int hashCode() {
> >>  +        return getName().hashCode();
> >>  +    }
> >>  +
> >>  +}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
> >
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
> >>  new file mode 100644
> >>  index 0000000..eb56c1d
> >>  --- /dev/null
> >>  +++
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
> >>  @@ -0,0 +1,93 @@
> >>  +/*
> >>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>  + * or more contributor license agreements.  See the NOTICE file
> >>  + * distributed with this work for additional information
> >>  + * regarding copyright ownership.  The ASF licenses this file
> >>  + * to you under the Apache License, Version 2.0 (the
> >>  + * "License"); you may not use this file except in compliance
> >>  + * with the License.  You may obtain a copy of the License at
> >>  + *
> >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>  + *
> >>  + * Unless required by applicable law or agreed to in writing,
> >>  + * software distributed under the License is distributed on an
> >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  + * KIND, either express or implied.  See the License for the
> >>  + * specific language governing permissions and limitations
> >>  + * under the License.
> >>  + */
> >>  +package org.apache.tamaya.core.internal.resource;
> >>  +
> >>  +import org.apache.tamaya.core.resources.Resource;
> >>  +import org.apache.tamaya.core.resources.ResourceLoader;
> >>  +
> >>  +import javax.annotation.Priority;
> >>  +import java.io.File;
> >>  +import java.net.URL;
> >>  +import java.util.ArrayList;
> >>  +import java.util.Collection;
> >>  +import java.util.Enumeration;
> >>  +import java.util.List;
> >>  +import java.util.logging.Logger;
> >>  +
> >>  +/**
> >>  + * Simple default implementation of the resource loader, which does
> only
> >>  support direct references to files.
> >>  + */
> >>  +@Priority(0)
> >>  +public class DefaultResourceLoader implements ResourceLoader {
> >>  +
> >>  +    private static final Logger LOG =
> >>  Logger.getLogger(DefaultResourceLoader.class.getName());
> >>  +
> >>  +    @Override
> >>  +    public List<Resource> getResources(ClassLoader classLoader,
> >>  Collection<String> expressions) {
> >>  +        List<Resource> resources = new ArrayList<>();
> >>  +        for (String expression : expressions) {
> >>  +            if (tryClassPath(classLoader, expression, resources) ||
> >>  tryFile(expression, resources) ||
> >>  +                    tryURL(expression, resources)) {
> >>  +                continue;
> >>  +            }
> >>  +            LOG.warning("Failed to resolve resource: " +
> > expression);
> >>  +        }
> >>  +        return resources;
> >>  +    }
> >>  +
> >>  +    private boolean tryClassPath(ClassLoader classLoader, String
> > expression,
> >>  List<Resource> resources) {
> >>  +        try {
> >>  +            Enumeration<URL> urls =
> > classLoader.getResources(expression);
> >>  +            while (urls.hasMoreElements()) {
> >>  +                URL url = urls.nextElement();
> >>  +                resources.add(new URLResource(url));
> >>  +            }
> >>  +            return !resources.isEmpty();
> >>  +        } catch (Exception e) {
> >>  +            LOG.finest(() -> "Failed to load resource from CP:
> > " +
> >>  expression);
> >>  +        }
> >>  +        return false;
> >>  +    }
> >>  +
> >>  +    private boolean tryFile(String expression, List<Resource>
> > resources)
> >>  {
> >>  +        try {
> >>  +            File file = new File(expression);
> >>  +            if (file.exists()) {
> >>  +                resources.add(new FileResource(file));
> >>  +                return true;
> >>  +            }
> >>  +        } catch (Exception e) {
> >>  +            LOG.finest(() -> "Failed to load resource from file:
> > "
> >>  + expression);
> >>  +        }
> >>  +        return false;
> >>  +    }
> >>  +
> >>  +    private boolean tryURL(String expression, List<Resource>
> > resources)
> >>  {
> >>  +        try {
> >>  +            URL url = new URL(expression);
> >>  +            resources.add(new URLResource(url));
> >>  +            return true;
> >>  +        } catch (Exception e) {
> >>  +            LOG.finest(() -> "Failed to load resource from file:
> > "
> >>  + expression);
> >>  +        }
> >>  +        return false;
> >>  +
> >>  +    }
> >>  +
> >>  +}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
> >>  new file mode 100644
> >>  index 0000000..e0096e5
> >>  --- /dev/null
> >>  +++
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
> >>  @@ -0,0 +1,162 @@
> >>  +/*
> >>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>  + * or more contributor license agreements.  See the NOTICE file
> >>  + * distributed with this work for additional information
> >>  + * regarding copyright ownership.  The ASF licenses this file
> >>  + * to you under the Apache License, Version 2.0 (the
> >>  + * "License"); you may not use this file except in compliance
> >>  + * with the License.  You may obtain a copy of the License at
> >>  + *
> >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>  + *
> >>  + * Unless required by applicable law or agreed to in writing,
> >>  + * software distributed under the License is distributed on an
> >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  + * KIND, either express or implied.  See the License for the
> >>  + * specific language governing permissions and limitations
> >>  + * under the License.
> >>  + */
> >>  +package org.apache.tamaya.core.internal.resource;
> >>  +
> >>  +import org.apache.tamaya.core.resources.Resource;
> >>  +
> >>  +import java.io.File;
> >>  +import java.io.FileInputStream;
> >>  +import java.io.IOException;
> >>  +import java.io.InputStream;
> >>  +import java.net.URI;
> >>  +import java.util.Objects;
> >>  +
> >>  +/**
> >>  + * Implementation of {@link
> > org.apache.tamaya.core.resources.Resource} to
> >>  be loaded from a file.
> >>  + * @see java.io.File
> >>  + */
> >>  +public class FileResource implements Resource {
> >>  +
> >>  +    private final File file;
> >>  +
> >>  +    /**
> >>  +     * Creates a new instance.
> >>  +     *
> >>  +     * @param file a File, not null.
> >>  +     */
> >>  +    public FileResource(File file) {
> >>  +        this.file = Objects.requireNonNull(file, "File must not be
> >>  null");
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Crreates a new instance.
> >>  +     *
> >>  +     * @param filePath a file path
> >>  +     */
> >>  +    public FileResource(String filePath) {
> >>  +        Objects.requireNonNull(filePath, "Path must not be
> > null");
> >>  +        this.file = new File(filePath);
> >>  +    }
> >>  +
> >>  +
> >>  +    /**
> >>  +     * Get the file path for this resource.
> >>  +     */
> >>  +    public final String getPath() {
> >>  +        return this.file.getPath();
> >>  +    }
> >>  +
> >>  +
> >>  +    /**
> >>  +     * This implementation returns whether the underlying file exists.
> >>  +     *
> >>  +     * @see java.io.File#exists()
> >>  +     */
> >>  +    @Override
> >>  +    public boolean exists() {
> >>  +        return this.file.exists();
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * This implementation checks whether the underlying file is
> marked as
> >
> >>  readable
> >>  +     * (and corresponds to an actual file with content, not to a
> > directory).
> >>  +     *
> >>  +     * @see java.io.File#canRead()
> >>  +     * @see java.io.File#isDirectory()
> >>  +     */
> >>  +    @Override
> >>  +    public boolean isAccessible() {
> >>  +        return (this.file.canRead() && !this.file.isDirectory());
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * This implementation opens a FileInputStream for the underlying
> > file.
> >>  +     *
> >>  +     * @see java.io.FileInputStream
> >>  +     */
> >>  +    @Override
> >>  +    public InputStream getInputStream() throws IOException {
> >>  +        return new FileInputStream(this.file);
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * This implementation returns a URI for the underlying file.
> >>  +     *
> >>  +     * @see java.io.File#toURI()
> >>  +     */
> >>  +    @Override
> >>  +    public URI toURI() throws IOException {
> >>  +        return this.file.toURI();
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Returns the underlying File's length.
> >>  +     */
> >>  +    @Override
> >>  +    public long length() throws IOException {
> >>  +        return this.file.length();
> >>  +    }
> >>  +
> >>  +    @Override
> >>  +    public long lastModified() throws IOException {
> >>  +        return file.lastModified();
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Returns the name of the current file.
> >>  +     *
> >>  +     * @see java.io.File#getName()
> >>  +     */
> >>  +    @Override
> >>  +    public String getName() {
> >>  +        return this.file.getName();
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Returns a description that includes the absolute
> >>  +     * path of the current file.
> >>  +     *
> >>  +     * @see java.io.File#getAbsolutePath()
> >>  +     */
> >>  +    @Override
> >>  +    public String toString() {
> >>  +        return "File [" + this.file.getAbsolutePath() +
> >>  "]";
> >>  +    }
> >>  +
> >>  +
> >>  +    // implementation current WritableResource
> >>  +
> >>  +    /**
> >>  +     * Compares the underlying Files.
> >>  +     */
> >>  +    @Override
> >>  +    public boolean equals(Object obj) {
> >>  +        return (obj == this ||
> >>  +                (obj instanceof FileResource &&
> >>  this.file.equals(((FileResource) obj).file)));
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Returns hash code current the underlying File reference.
> >>  +     */
> >>  +    @Override
> >>  +    public int hashCode() {
> >>  +        return this.file.hashCode();
> >>  +    }
> >>  +
> >>  +}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
> >
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
> >>  new file mode 100644
> >>  index 0000000..09510b4
> >>  --- /dev/null
> >>  +++
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
> >>  @@ -0,0 +1,117 @@
> >>  +/*
> >>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>  + * or more contributor license agreements.  See the NOTICE file
> >>  + * distributed with this work for additional information
> >>  + * regarding copyright ownership.  The ASF licenses this file
> >>  + * to you under the Apache License, Version 2.0 (the
> >>  + * "License"); you may not use this file except in compliance
> >>  + * with the License.  You may obtain a copy of the License at
> >>  + *
> >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>  + *
> >>  + * Unless required by applicable law or agreed to in writing,
> >>  + * software distributed under the License is distributed on an
> >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  + * KIND, either express or implied.  See the License for the
> >>  + * specific language governing permissions and limitations
> >>  + * under the License.
> >>  + */
> >>  +package org.apache.tamaya.core.internal.resource;
> >>  +
> >>  +import org.apache.tamaya.core.resources.Resource;
> >>  +
> >>  +import java.io.IOException;
> >>  +import java.io.InputStream;
> >>  +import java.net.URI;
> >>  +import java.util.Objects;
> >>  +
> >>  +/**
> >>  + * Simple Resource encapsulating an InputStream.
> >>  + */
> >>  +public class InputStreamResource implements Resource {
> >>  +
> >>  +    /** The InputStream. */
> >>  +    private final InputStream inputStream;
> >>  +    /** The read flag. */
> >>  +    private boolean read = false;
> >>  +    /** The name of the resource. */
> >>  +    private String name;
> >>  +
> >>  +
> >>  +    /**
> >>  +     * Create a new InputStreamResource.
> >>  +     *
> >>  +     * @param inputStream the InputStream to use
> >>  +     */
> >>  +    public InputStreamResource(InputStream inputStream) {
> >>  +        this(inputStream, "InputStream:");
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Create a new InputStreamResource.
> >>  +     *
> >>  +     * @param inputStream the InputStream to use
> >>  +     * @param name where the InputStream comes from
> >>  +     */
> >>  +    public InputStreamResource(InputStream inputStream, String name)
> > {
> >>  +        this.inputStream = Objects.requireNonNull(inputStream);
> >>  +        this.name = (name != null ? name : "InputStream");
> >>  +    }
> >>  +
> >>  +
> >>  +    /**
> >>  +     * This implementation always returns {@code true}.
> >>  +     */
> >>  +    @Override
> >>  +    public boolean exists() {
> >>  +        return true;
> >>  +    }
> >>  +
> >>  +    @Override
> >>  +    public URI toURI() throws IOException {
> >>  +        throw new IOException("URI not available.");
> >>  +    }
> >>  +
> >>  +    @Override
> >>  +    public long lastModified() throws IOException {
> >>  +        throw new IOException("lastModified not available.");
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Accesses the input stream. Hereby the input stream can only
> > accessed
> >>  once.
> >>  +     */
> >>  +    @Override
> >>  +    public InputStream getInputStream() throws IOException {
> >>  +        if (this.read) {
> >>  +            throw new IllegalStateException("InputStream can only be
> > read
> >>  once!");
> >>  +        }
> >>  +        this.read = true;
> >>  +        return this.inputStream;
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * This implementation returns the passed-in description, if any.
> >>  +     */
> >>  +    public String toString() {
> >>  +        return this.name != null ? this.name : super.toString();
> >>  +    }
> >>  +
> >>  +
> >>  +    /**
> >>  +     * Compares the underlying InputStream.
> >>  +     */
> >>  +    @Override
> >>  +    public boolean equals(Object obj) {
> >>  +        return (obj == this ||
> >>  +                (obj instanceof InputStreamResource &&
> >>  ((InputStreamResource) obj).inputStream.equals(this.inputStream)));
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * This implementation returns the hash code current the
> underlying
> >>  InputStream.
> >>  +     */
> >>  +    @Override
> >>  +    public int hashCode() {
> >>  +        return this.inputStream.hashCode();
> >>  +    }
> >>  +
> >>  +}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
> >>  new file mode 100644
> >>  index 0000000..4da6c53
> >>  --- /dev/null
> >>  +++
> >>
> >
> b/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
> >>  @@ -0,0 +1,37 @@
> >>  +/*
> >>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>  + * or more contributor license agreements.  See the NOTICE file
> >>  + * distributed with this work for additional information
> >>  + * regarding copyright ownership.  The ASF licenses this file
> >>  + * to you under the Apache License, Version 2.0 (the
> >>  + * "License"); you may not use this file except in compliance
> >>  + * with the License.  You may obtain a copy of the License at
> >>  + *
> >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>  + *
> >>  + * Unless required by applicable law or agreed to in writing,
> >>  + * software distributed under the License is distributed on an
> >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  + * KIND, either express or implied.  See the License for the
> >>  + * specific language governing permissions and limitations
> >>  + * under the License.
> >>  + */
> >>  +package org.apache.tamaya.core.resources;
> >>  +
> >>  +import java.io.IOException;
> >>  +import java.io.InputStream;
> >>  +
> >>  +/**
> >>  + * Simple interface for a component that provides data based on an
> > InputStream.
> >>  + */
> >>  +@FunctionalInterface
> >>  +public interface InputStreamSupplier {
> >>  +
> >>  +    /**
> >>  +     * Access the input stream.
> >>  +     * @return the input stream for use.
> >>  +     * @throws IOException i the input stream could not be obtained.
> >>  +     */
> >>  +    InputStream getInputStream() throws IOException;
> >>  +
> >>  +}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> > a/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
> >>  b/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
> >>  new file mode 100644
> >>  index 0000000..31c679d
> >>  --- /dev/null
> >>  +++ b/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
> >>  @@ -0,0 +1,115 @@
> >>  +/*
> >>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>  + * or more contributor license agreements.  See the NOTICE file
> >>  + * distributed with this work for additional information
> >>  + * regarding copyright ownership.  The ASF licenses this file
> >>  + * to you under the Apache License, Version 2.0 (the
> >>  + * "License"); you may not use this file except in compliance
> >>  + * with the License.  You may obtain a copy of the License at
> >>  + *
> >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>  + *
> >>  + * Unless required by applicable law or agreed to in writing,
> >>  + * software distributed under the License is distributed on an
> >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  + * KIND, either express or implied.  See the License for the
> >>  + * specific language governing permissions and limitations
> >>  + * under the License.
> >>  + */
> >>  +package org.apache.tamaya.core.resources;
> >>  +
> >>  +import java.io.File;
> >>  +import java.io.IOException;
> >>  +import java.io.InputStream;
> >>  +import java.net.URI;
> >>  +import java.net.URL;
> >>  +import java.util.Objects;
> >>  +
> >>  +/**
> >>  + * Interface for an abstract resource. The effective resource
> > implementation
> >>  can be completely arbitrary.
> >>  + * By default files, classpath resources and URLs are supported, but
> > alternate
> >>  implementations are possible.
> >>  + *
> >>  + * @see #getInputStream()
> >>  + * @see #toURI()
> >>  + */
> >>  +public interface Resource extends InputStreamSupplier {
> >>  +
> >>  +    /**
> >>  +     * Return whether this resource actually exists. Depending on the
> > resource
> >>  this can delegate to
> >>  +     * {@link java.io.File#exists()} or whatever may be appropriate
> > to
> >>  check accessibility of the resource.
> >>  +     */
> >>  +    default boolean exists() {
> >>  +        // Try to open a file first, if that fails try to open the
> > stream...
> >>  +        try {
> >>  +            return new File(toURI()).exists();
> >>  +        } catch (IOException ex) {
> >>  +            // Fallback
> >>  +            try {
> >>  +                InputStream is = getInputStream();
> >>  +                is.close();
> >>  +                return true;
> >>  +            } catch (Exception e) {
> >>  +                // ignore, just return false for non existing
> >>  +                return false;
> >>  +            }
> >>  +        }
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Checks whether the resource is accessible, meaning {@link
> >>  #getInputStream()} should return a InputStream for reading the
> >>  +     * resource's content.
> >>  +     *
> >>  +     * @see #getInputStream()
> >>  +     */
> >>  +    default boolean isAccessible() {
> >>  +        return true;
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Returns the resource as an URI.
> >>  +     *
> >>  +     * @throws IOException if the resource cannot be resolved as URI.
> >>  +     */
> >>  +    URI toURI() throws IOException;
> >>  +
> >>  +    /**
> >>  +     * Determines the length for this resource.
> >>  +     *
> >>  +     * @throws IOException if the resource is not readable.
> >>  +     */
> >>  +    default long length() throws IOException {
> >>  +        try(InputStream is = this.getInputStream();) {
> >>  +            Objects.requireNonNull(is, "resource not
> > available");
> >>  +            long length = 0;
> >>  +            byte[] buf = new byte[256];
> >>  +            int bytesRead;
> >>  +            while ((bytesRead = is.read(buf)) > 0) {
> >>  +                length += bytesRead;
> >>  +            }
> >>  +            return length;
> >>  +        }
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Determine the last-modified timestamp for a resource, as UTC ms
> >>  timestamp
> >>  +     *
> >>  +     * @throws IOException if the resource is not accessible.
> >>  +     */
> >>  +    default long lastModified() throws IOException{
> >>  +        return new File(toURI()).lastModified();
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Get a name for the resource. The name should be identifying the
> > resource
> >>  and also
> >>  +     * never change, so it must be eligible for hashcode/equals
> >>  implementations.
> >>  +     */
> >>  +    default String getName() {
> >>  +        try {
> >>  +            return toURI().toString();
> >>  +        } catch (Exception e) {
> >>  +            return toString();
> >>  +        }
> >>  +    }
> >>  +
> >>  +
> >>  +}
> >>  \ No newline at end of file
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> a/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
> >>
> b/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
> >>  new file mode 100644
> >>  index 0000000..5aff10a
> >>  --- /dev/null
> >>  +++
> > b/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
> >>  @@ -0,0 +1,91 @@
> >>  +/*
> >>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>  + * or more contributor license agreements.  See the NOTICE file
> >>  + * distributed with this work for additional information
> >>  + * regarding copyright ownership.  The ASF licenses this file
> >>  + * to you under the Apache License, Version 2.0 (the
> >>  + * "License"); you may not use this file except in compliance
> >>  + * with the License.  You may obtain a copy of the License at
> >>  + *
> >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>  + *
> >>  + * Unless required by applicable law or agreed to in writing,
> >>  + * software distributed under the License is distributed on an
> >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  + * KIND, either express or implied.  See the License for the
> >>  + * specific language governing permissions and limitations
> >>  + * under the License.
> >>  + */
> >>  +package org.apache.tamaya.core.resources;
> >>  +
> >>  +import java.util.Arrays;
> >>  +import java.util.Collection;
> >>  +import java.util.List;
> >>  +
> >>  +/**
> >>  + * Interface to be implemented by modules. By default only direct
> > file/resource
> >>  resolution is supported, whereas
> >>  + * extension modules may add functionality to perform ant styled
> pattern
> >>  resolution of resources.
> >>  + */
> >>  +public interface ResourceLoader {
> >>  +
> >>  +    /**
> >>  +     * Resolves resource expressions to a list of {@link
> >>  org.apache.tamaya.core.resources.Resource}s. Hereby
> >>  +     * the ordering of resources matches the input of the resolved
> > expressions.
> >>  Nevertheless be aware that
> >>  +     * there is no determined ordering of resources located within a
> >>  classloader.
> >>  +     *
> >>  +     * @param expressions the expressions to be resolved, not empty.
> >>  +     * @return the corresponding collection of current {@link
> >>  org.apache.tamaya.core.resources.Resource}s found, never
> >>  +     * null.
> >>  +     * .
> >>  +     */
> >>  +    default Collection<Resource>
> > getResources(Collection<String>
> >>  expressions) {
> >>  +        ClassLoader cl =
> Thread.currentThread().getContextClassLoader();
> >>  +        if (cl == null) {
> >>  +            cl = getClass().getClassLoader();
> >>  +        }
> >>  +        return getResources(cl, expressions);
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Resolves resource expressions to a list of {@link
> >>  org.apache.tamaya.core.resources.Resource}s. Hereby
> >>  +     * the ordering of resources matches the input of the resolved
> > expressions.
> >>  Nevertheless be aware that
> >>  +     * there is no determined ordering of resources located within a
> >>  classloader.
> >>  +     *
> >>  +     * @param expressions the expressions to be resolved, not empty.
> >>  +     * @return the corresponding collection of current {@link
> >>  org.apache.tamaya.core.resources.Resource}s found, never
> >>  +     * null.
> >>  +     * .
> >>  +     */
> >>  +    default Collection<Resource> getResources(String... expressions)
> >
> >>  {
> >>  +        return getResources(Arrays.asList(expressions));
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Resolves resource expressions to a list of {@link
> >>  org.apache.tamaya.core.resources.Resource}s, considerubg
> >>  +     * the given classloader for classloader dependent resources.
> Hereby
> >>  +     * the ordering of resources matches the input of the resolved
> > expressions.
> >>  Nevertheless be aware that
> >>  +     * there is no determined ordering of resources located within a
> >>  classloader.
> >>  +     *
> >>  +     * @param expressions the expressions to be resolved, not empty.
> >>  +     * @return the corresponding collection of current {@link
> >>  org.apache.tamaya.core.resources.Resource}s found, never
> >>  +     * null.
> >>  +     * .
> >>  +     */
> >>  +    default Collection<Resource> getResources(ClassLoader
> > classLoader,
> >>  String... expressions){
> >>  +        return getResources(classLoader, Arrays.asList(expressions));
> >>  +    }
> >>  +
> >>  +    /**
> >>  +     * Resolves resource expressions to a list of {@link
> >>  org.apache.tamaya.core.resources.Resource}s, considerubg
> >>  +     * the given classloader for classloader dependent resources.
> Hereby
> >>  +     * the ordering of resources matches the input of the resolved
> > expressions.
> >>  Nevertheless be aware that
> >>  +     * there is no determined ordering of resources located within a
> >>  classloader.
> >>  +     *
> >>  +     * @param expressions the expressions to be resolved, not empty.
> >>  +     * @return the corresponding collection of current {@link
> >>  org.apache.tamaya.core.resources.Resource}s found, never
> >>  +     * null.
> >>  +     * .
> >>  +     */
> >>  +    Collection<Resource> getResources(ClassLoader classLoader,
> >>  Collection<String> expressions);
> >>  +
> >>  +}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> > a/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> >>  b/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> >>  index be1eadb..9c7b894 100644
> >>  --- a/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> >>  +++ b/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> >>  @@ -41,6 +41,12 @@ public class ConfigurationTest {
> >>           assertEquals("Lukas",
> >>  Configuration.current().get("name3").get());  // oderridden
> > default
> >>           assertEquals("Sereina",
> >>  Configuration.current().get("name4").get()); // final only
> >>           assertEquals("Benjamin",
> >>  Configuration.current().get("name5").get()); // final only
> >>  +
> >>  +        System.out.println("name : " +
> >>  Configuration.current().get("name").get());
> >>  +        System.out.println("name2: " +
> >>  Configuration.current().get("name2").get());
> >>  +        System.out.println("name3: " +
> >>  Configuration.current().get("name3").get());
> >>  +        System.out.println("name4: " +
> >>  Configuration.current().get("name4").get());
> >>  +        System.out.println("name5: " +
> >>  Configuration.current().get("name5").get());
> >>       }
> >>
> >>
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
> >
> >>
> >
> b/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
> >>  deleted file mode 100644
> >>  index 51cc2dc..0000000
> >>  ---
> >>
> >
> a/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
> >>  +++ /dev/null
> >>  @@ -1,70 +0,0 @@
> >>  -/*
> >>  - * Licensed to the Apache Software Foundation (ASF) under one
> >>  - * or more contributor license agreements.  See the NOTICE file
> >>  - * distributed with this work for additional information
> >>  - * regarding copyright ownership.  The ASF licenses this file
> >>  - * to you under the Apache License, Version 2.0 (the
> >>  - * "License"); you may not use this file except in compliance
> >>  - * with the License.  You may obtain a copy of the License at
> >>  - *
> >>  - * http://www.apache.org/licenses/LICENSE-2.0
> >>  - *
> >>  - * Unless required by applicable law or agreed to in writing,
> >>  - * software distributed under the License is distributed on an
> >>  - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  - * KIND, either express or implied.  See the License for the
> >>  - * specific language governing permissions and limitations
> >>  - * under the License.
> >>  - */
> >>  -package org.apache.tamaya.core.test.propertysource;
> >>  -
> >>  -import org.apache.tamaya.core.propertysource.DefaultOrdinal;
> >>  -import
> org.apache.tamaya.core.propertysource.EnvironmentPropertySource;
> >>  -import org.junit.Assert;
> >>  -import org.junit.Test;
> >>  -
> >>  -import java.util.Map;
> >>  -import java.util.Optional;
> >>  -
> >>  -public class EnvironmentPropertySourceTest {
> >>  -
> >>  -    private EnvironmentPropertySource propertySource = new
> >>  EnvironmentPropertySource();
> >>  -
> >>  -
> >>  -    @Test
> >>  -    public void testGetOrdinal() {
> >>  -        Assert.assertEquals(DefaultOrdinal.ENVIRONMENT_PROPERTIES,
> >>  propertySource.getOrdinal());
> >>  -    }
> >>  -
> >>  -    @Test
> >>  -    public void testGet() {
> >>  -        String environmentPropertyToCheck =
> >>  System.getenv().keySet().iterator().next();
> >>  -
> >>  -        Optional<String> value =
> >>  propertySource.get(environmentPropertyToCheck);
> >>  -        Assert.assertTrue(value.isPresent());
> >>  -        Assert.assertEquals(System.getenv(environmentPropertyToCheck),
> >>  value.get());
> >>  -    }
> >>  -
> >>  -    @Test
> >>  -    public void testGetProperties() {
> >>  -        Map<String, String> environmentProperties = System.getenv();
> >>  -
> >>  -        Assert.assertEquals(environmentProperties.size(),
> >>  propertySource.getProperties().size());
> >>  -
> >>  -        for (Map.Entry<String, String> propertySourceEntry :
> >>  propertySource.getProperties().entrySet()) {
> >>  -            Assert.assertEquals("Entry values for key '" +
> >>  propertySourceEntry.getKey() + "' do not match",
> >>  -
> >>  environmentProperties.get(propertySourceEntry.getKey()),
> >>  propertySourceEntry.getValue());
> >>  -        }
> >>  -
> >>  -        // modification is not allowed
> >>  -        try {
> >>  -            propertySource.getProperties().put("add.new.keys",
> >>  "must throw exception");
> >>  -            Assert.fail(UnsupportedOperationException.class.getName()
> +
> > "
> >>  expected");
> >>  -        }
> >>  -        catch (UnsupportedOperationException e) {
> >>  -            // expected -> all is fine
> >>  -        }
> >>  -    }
> >>  -
> >>  -
> >>  -}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
> >
> >>
> >
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
> >>  new file mode 100644
> >>  index 0000000..5fa90b1
> >>  --- /dev/null
> >>  +++
> >>
> >
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
> >>  @@ -0,0 +1,32 @@
> >>  +/*
> >>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>  + * or more contributor license agreements.  See the NOTICE file
> >>  + * distributed with this work for additional information
> >>  + * regarding copyright ownership.  The ASF licenses this file
> >>  + * to you under the Apache License, Version 2.0 (the
> >>  + * "License"); you may not use this file except in compliance
> >>  + * with the License.  You may obtain a copy of the License at
> >>  + *
> >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>  + *
> >>  + * Unless required by applicable law or agreed to in writing,
> >>  + * software distributed under the License is distributed on an
> >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  + * KIND, either express or implied.  See the License for the
> >>  + * specific language governing permissions and limitations
> >>  + * under the License.
> >>  + */
> >>  +package org.apache.tamaya.core.testdata;
> >>  +
> >>  +import org.apache.tamaya.core.PathBasedPropertySourceProvider;
> >>  +import org.apache.tamaya.core.formats.PropertiesFormat;
> >>  +
> >>  +/**
> >>  + * Test provider reading properties from
> > classpath:cfg/defaults/**.properties.
> >>  + */
> >>  +public class TestPropertyDefaultSourceProvider extends
> >>  PathBasedPropertySourceProvider{
> >>  +
> >>  +    public TestPropertyDefaultSourceProvider() {
> >>  +        super("default-testdata-properties", new
> >>  PropertiesFormat(100), "classpath:cfg/defaults/**/*.properties");
> >>  +    }
> >>  +}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
> >>
> >
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
> >>  deleted file mode 100644
> >>  index d1314aa..0000000
> >>  ---
> >
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
> >>  +++ /dev/null
> >>  @@ -1,55 +0,0 @@
> >>  -/*
> >>  - * Licensed to the Apache Software Foundation (ASF) under one
> >>  - * or more contributor license agreements.  See the NOTICE file
> >>  - * distributed with this work for additional information
> >>  - * regarding copyright ownership.  The ASF licenses this file
> >>  - * to you under the Apache License, Version 2.0 (the
> >>  - * "License"); you may not use this file except in compliance
> >>  - * with the License.  You may obtain a copy of the License at
> >>  - *
> >>  - *  http://www.apache.org/licenses/LICENSE-2.0
> >>  - *
> >>  - * Unless required by applicable law or agreed to in writing,
> >>  - * software distributed under the License is distributed on an
> >>  - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  - * KIND, either express or implied.  See the License for the
> >>  - * specific language governing permissions and limitations
> >>  - * under the License.
> >>  - */
> >>  -package org.apache.tamaya.core.testdata;
> >>  -
> >>  -import java.util.HashMap;
> >>  -import java.util.Map;
> >>  -
> >>  -import org.apache.tamaya.core.propertysource.BasePropertySource;
> >>  -
> >>  -/**
> >>  - * Test provider reading properties from
> > classpath:cfg/final/**.properties.
> >>  - */
> >>  -public class TestPropertySource extends BasePropertySource {
> >>  -
> >>  -    private static final Map<String, String> VALUES;
> >>  -    static {
> >>  -        VALUES = new HashMap<String, String>();
> >>  -        VALUES.put("name", "Robin");
> >>  -        VALUES.put("name2", "Sabine");
> >>  -        VALUES.put("name3", "Lukas");
> >>  -        VALUES.put("name4", "Sereina");
> >>  -        VALUES.put("name5", "Benjamin");
> >>  -    }
> >>  -
> >>  -
> >>  -    public TestPropertySource() {
> >>  -        initialzeOrdinal(100);
> >>  -    }
> >>  -
> >>  -    @Override
> >>  -    public String getName() {
> >>  -        return "TestPropertySource";
> >>  -    }
> >>  -
> >>  -    @Override
> >>  -    public Map<String, String> getProperties() {
> >>  -        return VALUES;
> >>  -    }
> >>  -}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
> >
> >>
> >
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
> >>  new file mode 100644
> >>  index 0000000..beafbf9
> >>  --- /dev/null
> >>  +++
> >>
> >
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
> >>  @@ -0,0 +1,32 @@
> >>  +/*
> >>  + * Licensed to the Apache Software Foundation (ASF) under one
> >>  + * or more contributor license agreements.  See the NOTICE file
> >>  + * distributed with this work for additional information
> >>  + * regarding copyright ownership.  The ASF licenses this file
> >>  + * to you under the Apache License, Version 2.0 (the
> >>  + * "License"); you may not use this file except in compliance
> >>  + * with the License.  You may obtain a copy of the License at
> >>  + *
> >>  + *  http://www.apache.org/licenses/LICENSE-2.0
> >>  + *
> >>  + * Unless required by applicable law or agreed to in writing,
> >>  + * software distributed under the License is distributed on an
> >>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  + * KIND, either express or implied.  See the License for the
> >>  + * specific language governing permissions and limitations
> >>  + * under the License.
> >>  + */
> >>  +package org.apache.tamaya.core.testdata;
> >>  +
> >>  +import org.apache.tamaya.core.PathBasedPropertySourceProvider;
> >>  +import org.apache.tamaya.core.formats.PropertiesFormat;
> >>  +
> >>  +/**
> >>  + * Test provider reading properties from
> > classpath:cfg/final/**.properties.
> >>  + */
> >>  +public class TestPropertySourceProvider extends
> >>  PathBasedPropertySourceProvider{
> >>  +
> >>  +    public TestPropertySourceProvider() {
> >>  +        super("final-testdata-properties", new
> > PropertiesFormat(200),
> >>  "classpath:cfg/final/**/*.properties");
> >>  +    }
> >>  +}
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
> >
> >>
> >
> b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
> >>  deleted file mode 100644
> >>  index e6f7fad..0000000
> >>  ---
> >>
> >
> a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
> >>  +++ /dev/null
> >>  @@ -1,19 +0,0 @@
> >>  -#
> >>  -# Licensed to the Apache Software Foundation (ASF) under one
> >>  -# or more contributor license agreements.  See the NOTICE file
> >>  -# distributed with this work for additional information
> >>  -# regarding copyright ownership.  The ASF licenses this file
> >>  -# to you under the Apache License, Version 2.0 (the
> >>  -# "License"); you may not use this file except in compliance
> >>  -# with the License.  You may obtain a copy current the License at
> >>  -#
> >>  -#    http://www.apache.org/licenses/LICENSE-2.0
> >>  -#
> >>  -# Unless required by applicable law or agreed to in writing,
> >>  -# software distributed under the License is distributed on an
> >>  -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  -# KIND, either express or implied.  See the License for the
> >>  -# specific language governing permissions and limitations
> >>  -# under the License.
> >>  -#
> >>  -org.apache.tamaya.core.testdata.TestPropertySource
> >>  \ No newline at end of file
> >>
> >>
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
> >>  ----------------------------------------------------------------------
> >>  diff --git
> >>
> >
> a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
> >
> >>
> >
> b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
> >>  new file mode 100644
> >>  index 0000000..9db0ef4
> >>  --- /dev/null
> >>  +++
> >>
> >
> b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
> >>  @@ -0,0 +1,20 @@
> >>  +#
> >>  +# Licensed to the Apache Software Foundation (ASF) under one
> >>  +# or more contributor license agreements.  See the NOTICE file
> >>  +# distributed with this work for additional information
> >>  +# regarding copyright ownership.  The ASF licenses this file
> >>  +# to you under the Apache License, Version 2.0 (the
> >>  +# "License"); you may not use this file except in compliance
> >>  +# with the License.  You may obtain a copy current the License at
> >>  +#
> >>  +#    http://www.apache.org/licenses/LICENSE-2.0
> >>  +#
> >>  +# Unless required by applicable law or agreed to in writing,
> >>  +# software distributed under the License is distributed on an
> >>  +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> >>  +# KIND, either express or implied.  See the License for the
> >>  +# specific language governing permissions and limitations
> >>  +# under the License.
> >>  +#
> >>  +org.apache.tamaya.core.testdata.TestPropertyDefaultSourceProvider
> >>  +org.apache.tamaya.core.testdata.TestPropertySourceProvider
> >>  \ No newline at end of file
> >>
> >
>



-- 
*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 <%2B41-76%20344%2062%2079>*

Re: [2/4] incubator-tamaya git commit: TAMAYA-42, 43, 44: Readded non Spring related parts. Simplified resource API. Readded other tests.

Posted by Mark Struberg <st...@yahoo.de>.
I just became aware that maybe my VOTE was not clear enough.

> 2.) Wouldn't it be easier to write the functionality ourselves 
> and be able to only implement the pieces we really need? 
> Currently all we need is ClassLoader.getResources() and be done.

My aim was not to implement ALL the functionality originally taken from Spring but really only the things we need.
And essentially the following:

> Currently all we need is ClassLoader.getResources() and be done.


Reading Properties from a resource is essentially a single line of code:


java.util.Properties.load(ClassLoader.getResource(fileUrl).openStream());

I don't yet get the benefit of the other code. Please explain.


LieGrue,
strub





> On Sunday, 4 January 2015, 9:10, Mark Struberg <st...@yahoo.de> wrote:
> > Anatole, WHY do we need all of this?
> 
> It is NOWHERE used!
> 
> Why do we add 21 classes which don't provide anything useful to the project?
> There was even a VOTE that we should keep it simple and just do the things we 
> need.
> 
> I really don't get it. Is our goal to create a lightweight but flexible 
> configuration system or is our goal to become big and fat?
> 
> 
> Maybe it makes sense but if so then please explain it to us.
> 
> 
> 1.) Why do we read in a specific format? 
> 
> All the system is handling String/String and only in the last step it *probably* 
> gets converted into a target Type. I fail to see the benefit. Please explain it 
> to us.
> 
> 2.) Why do we need all the Resource implementations?
> 
> Java provides Resource handling out of the box. Again: we don't need any 
> scripting. So why add some handling for dynamic scenarios which we do not have? 
> This is basically a copy of Spring.io. But we simply don't have anything 
> scripted in XML as Spring does. So why should we add it?
> 
> 
> I'm really tired of seeing code all over the place which is not helpful for 
> the project. Please don't add things we don't really need.
> 
> 
> LieGrue,
> strub
> 
> 
> 
> 
> 
> 
> 
>>  On Sunday, 4 January 2015, 2:52, "anatole@apache.org" 
> <an...@apache.org> wrote:
>>  >T AMAYA-42,43,44: Readded non Spring related parts. Simplified resource 
> API. 
>>  Readded other tests.
>> 
>> 
>>  Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo
>>  Commit: 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/cc237eb4
>>  Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/cc237eb4
>>  Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/cc237eb4
>> 
>>  Branch: refs/heads/master
>>  Commit: cc237eb41b7d0c660261f451f47bbf07b7770c46
>>  Parents: 59a9e21
>>  Author: anatole <an...@apache.org>
>>  Authored: Sun Jan 4 02:17:56 2015 +0100
>>  Committer: anatole <an...@apache.org>
>>  Committed: Sun Jan 4 02:26:23 2015 +0100
>> 
>>  ----------------------------------------------------------------------
>>  .../org/apache/tamaya/spi/PropertyFilter.java   |  10 +-
>>  .../core/PathBasedPropertySourceProvider.java   |  93 ++++++++++
>>  .../core/ResourcePropertySourceProvider.java    | 102 +++++++++++
>>  .../core/formats/ConfigurationFormat.java       |  53 ++++++
>>  .../tamaya/core/formats/PropertiesFormat.java   | 114 ++++++++++++
>>  .../core/formats/PropertiesXmlFormat.java       | 115 ++++++++++++
>>  .../core/internal/DefaultConfiguration.java     |  27 ++-
>>  .../internal/resource/ClassPathResource.java    | 178 +++++++++++++++++++
>>  .../resource/DefaultResourceLoader.java         |  93 ++++++++++
>>  .../core/internal/resource/FileResource.java    | 162 +++++++++++++++++
>>  .../internal/resource/InputStreamResource.java  | 117 ++++++++++++
>>  .../core/resources/InputStreamSupplier.java     |  37 ++++
>>  .../apache/tamaya/core/resources/Resource.java  | 115 ++++++++++++
>>  .../tamaya/core/resources/ResourceLoader.java   |  91 ++++++++++
>>  .../apache/tamaya/core/ConfigurationTest.java   |   6 +
>>  .../EnvironmentPropertySourceTest.java          |  70 --------
>>  .../TestPropertyDefaultSourceProvider.java      |  32 ++++
>>  .../core/testdata/TestPropertySource.java       |  55 ------
>>  .../testdata/TestPropertySourceProvider.java    |  32 ++++
>>  .../org.apache.tamaya.spi.PropertySource        |  19 --
>>  ...org.apache.tamaya.spi.PropertySourceProvider |  20 +++
>>  21 files changed, 1388 insertions(+), 153 deletions(-)
>>  ----------------------------------------------------------------------
>> 
>> 
>> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
>>  ----------------------------------------------------------------------
>>  diff --git a/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java 
>>  b/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
>>  index 7479008..c8626fc 100644
>>  --- a/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
>>  +++ b/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
>>  @@ -19,7 +19,7 @@
>>  package org.apache.tamaya.spi;
>> 
>> 
>>  -import java.util.Map;
>>  +import java.util.function.Function;
>> 
>>  /**
>>    * <p>Interface for filtering the current map of properties during 
> the 
>>  evaluation of the chain of PropertySources.
>>  @@ -27,7 +27,7 @@ import java.util.Map;
>>    * hereby is defined by the corresponding {@code @Priority} 
>>  annotation.</p>
>>    * <p>Filters </p>
>>    */
>>  -public interface PropertyFilter<T>{
>>  +public interface PropertyFilter{
>> 
>>       /**
>>        * <p>Maps the current {@code valueToBeFiltered} value to a 
> new 
>>  value. The resulting value will be used as the result
>>  @@ -44,10 +44,10 @@ public interface PropertyFilter<T>{
>>        *
>>        * @param key the key accessed, not null.
>>        * @param valueToBeFiltered the value to be filtered, not null.
>>  -     * @param currentMap the current input property map, not null. Can be 
> used 
>>  for resolution of the filtered value
>>  -     *                   or as datasource for additional meta-information, 
> such 
>>  as categories, sensitivity etc.
>>  +     * @param propertyValueProvider accessor for reading additional (eg 
>>  metadata) properties to perform correct
>>  +     *                              filtering, never null.
>>        * @return the filtered map, never null.
>>        */
>>  -    String filterProperty(String key, String valueToBeFiltered, 
>>  Map<String,String> currentMap);
>>  +    String filterProperty(String key, String valueToBeFiltered, 
>>  Function<String,String> propertyValueProvider);
>> 
>>  }
>> 
>> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
>>  ----------------------------------------------------------------------
>>  diff --git 
>> 
> a/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java 
> 
>> 
> b/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
>>  new file mode 100644
>>  index 0000000..31dbf4b
>>  --- /dev/null
>>  +++ 
>> 
> b/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
>>  @@ -0,0 +1,93 @@
>>  +/*
>>  + * Licensed to the Apache Software Foundation (ASF) under one
>>  + * or more contributor license agreements.  See the NOTICE file
>>  + * distributed with this work for additional information
>>  + * regarding copyright ownership.  The ASF licenses this file
>>  + * to you under the Apache License, Version 2.0 (the
>>  + * "License"); you may not use this file except in compliance
>>  + * with the License.  You may obtain a copy of the License at
>>  + *
>>  + *  http://www.apache.org/licenses/LICENSE-2.0
>>  + *
>>  + * Unless required by applicable law or agreed to in writing,
>>  + * software distributed under the License is distributed on an
>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>  + * KIND, either express or implied.  See the License for the
>>  + * specific language governing permissions and limitations
>>  + * under the License.
>>  + */
>>  +package org.apache.tamaya.core;
>>  +
>>  +import org.apache.tamaya.core.formats.ConfigurationFormat;
>>  +import org.apache.tamaya.core.resources.Resource;
>>  +import org.apache.tamaya.core.resources.ResourceLoader;
>>  +import org.apache.tamaya.spi.PropertySource;
>>  +import org.apache.tamaya.spi.PropertySourceProvider;
>>  +import org.apache.tamaya.spi.ServiceContext;
>>  +
>>  +import java.util.ArrayList;
>>  +import java.util.Arrays;
>>  +import java.util.Collection;
>>  +import java.util.List;
>>  +import java.util.Objects;
>>  +import java.util.logging.Level;
>>  +import java.util.logging.Logger;
>>  +
>>  +/**
>>  + * Implementation of a {@link PropertySourceProvider} that reads 
>>  configuration from some given resource paths
>>  + * and using the given formats. The resource path are resolved using the 
>>  current
>>  + * {@link org.apache.tamaya.core.resources.ResourceLoader} active.
>>  + */
>>  +public class PathBasedPropertySourceProvider implements 
> PropertySourceProvider 
>>  {
>>  +    /** The logger used. */
>>  +    private static final Logger LOG = 
>>  Logger.getLogger(PathBasedPropertySourceProvider.class.getName());
>>  +    /** The property source base name, will be used for creating a useful 
> name 
>>  of the
>>  +     * {@link org.apache.tamaya.spi.PropertySource} created. */
>>  +    private String sourceName;
>>  +    /** The config formats supported for the given location/resource 
> paths. */
>>  +    private List<ConfigurationFormat> configFormats = new 
>>  ArrayList<>();
>>  +    /** The paths to be evaluated. */
>>  +    private List<String> paths = new ArrayList<>();
>>  +
>>  +    /**
>>  +     * Creates a new instance.
>>  +     * @param sourceName the base name of the configuration, used for 
> creating 
>>  PropertySource child names.
>>  +     * @param formats the formats to be used, not null, not empty.
>>  +     * @param paths the paths to be resolved, not null, not empty.
>>  +     */
>>  +    public PathBasedPropertySourceProvider(String sourceName, 
>>  List<ConfigurationFormat> formats, String... paths) {
>>  +        this.sourceName = Objects.requireNonNull(sourceName);
>>  +        this.configFormats.addAll(Objects.requireNonNull(formats));
>>  +        this.paths.addAll(Arrays.asList(Objects.requireNonNull(paths)));
>>  +    }
>>  +
>>  +    /**
>>  +     * Creates a new instance.
>>  +     * @param sourceName the base name of the configuration, used for 
> creating 
>>  PropertySource child names.
>>  +     * @param format the format to be used.
>>  +     * @param paths the paths to be resolved, not null, not empty.
>>  +     */
>>  +    public PathBasedPropertySourceProvider(String sourceName, 
>>  ConfigurationFormat format, String... paths) {
>>  +        this.sourceName = Objects.requireNonNull(sourceName);
>>  +        this.configFormats.add(Objects.requireNonNull(format));
>>  +        this.paths.addAll(Arrays.asList(Objects.requireNonNull(paths)));
>>  +    }
>>  +
>>  +    @Override
>>  +    public Collection<PropertySource> getPropertySources() {
>>  +        List<PropertySource> propertySources = new 
> ArrayList<>();
>>  +        paths.forEach((path) -> {
>>  +            for (Resource res : 
>> 
> ServiceContext.getInstance().getService(ResourceLoader.class).get().getResources(path)) 
> 
>>  {
>>  +                try {
>>  +                    for (ConfigurationFormat format : configFormats) 
> {
>>  +                        
>>  propertySources.addAll(format.readConfiguration(sourceName, res));
>>  +                    }
>>  +                } catch (Exception e) {
>>  +                    LOG.log(Level.WARNING, "Failed to add resource 
> based 
>>  config: " + res.getName(), e);
>>  +                }
>>  +            }
>>  +        });
>>  +        return propertySources;
>>  +    }
>>  +
>>  +}
>> 
>> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
>>  ----------------------------------------------------------------------
>>  diff --git 
>> 
> a/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java 
>> 
> b/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
>>  new file mode 100644
>>  index 0000000..de6b578
>>  --- /dev/null
>>  +++ 
>> 
> b/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
>>  @@ -0,0 +1,102 @@
>>  +/*
>>  + * Licensed to the Apache Software Foundation (ASF) under one
>>  + * or more contributor license agreements.  See the NOTICE file
>>  + * distributed with this work for additional information
>>  + * regarding copyright ownership.  The ASF licenses this file
>>  + * to you under the Apache License, Version 2.0 (the
>>  + * "License"); you may not use this file except in compliance
>>  + * with the License.  You may obtain a copy of the License at
>>  + *
>>  + *  http://www.apache.org/licenses/LICENSE-2.0
>>  + *
>>  + * Unless required by applicable law or agreed to in writing,
>>  + * software distributed under the License is distributed on an
>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>  + * KIND, either express or implied.  See the License for the
>>  + * specific language governing permissions and limitations
>>  + * under the License.
>>  + */
>>  +package org.apache.tamaya.core;
>>  +
>>  +import org.apache.tamaya.core.formats.ConfigurationFormat;
>>  +import org.apache.tamaya.core.resources.Resource;
>>  +import org.apache.tamaya.spi.PropertySource;
>>  +import org.apache.tamaya.spi.PropertySourceProvider;
>>  +
>>  +import java.util.ArrayList;
>>  +import java.util.Arrays;
>>  +import java.util.Collection;
>>  +import java.util.List;
>>  +import java.util.Objects;
>>  +import java.util.logging.Logger;
>>  +
>>  +/**
>>  + * Implementation of a {@link 
>>  org.apache.tamaya.spi.PropertySourceProvider} that is based on a single 
> resource
>>  + * and a number of formats.
>>  + */
>>  +public class ResourcePropertySourceProvider implements 
> PropertySourceProvider 
>>  {
>>  +    /** The logger used. */
>>  +    private static final Logger LOG = 
>>  Logger.getLogger(ResourcePropertySourceProvider.class.getName());
>>  +    /** The supported formats. */
>>  +    private List<ConfigurationFormat> formats = new 
> ArrayList<>();
>>  +    /** The resource. */
>>  +    private Resource resource;
>>  +    /** The source name used for creating the PropertySource names. */
>>  +    private String sourceName;
>>  +
>>  +    /**
>>  +     * Creates a new instance.
>>  +     * @param resource the {@link 
>>  org.apache.tamaya.core.resources.Resource}, not null.
>>  +     * @param formats the supported formats, not empty.
>>  +     */
>>  +    public ResourcePropertySourceProvider(String sourceName, Resource 
> resource, 
>>  ConfigurationFormat... formats) {
>>  +        this(sourceName, resource, Arrays.asList(formats));
>>  +    }
>>  +
>>  +    /**
>>  +     * Creates a new instance.
>>  +     * @param resource the {@link 
>>  org.apache.tamaya.core.resources.Resource}, not null.
>>  +     * @param formats the supported formats, not empty.
>>  +     */
>>  +    public ResourcePropertySourceProvider(String sourceName, Resource 
> resource, 
>>  List<ConfigurationFormat> formats) {
>>  +        this.resource = Objects.requireNonNull(resource);
>>  +        this.sourceName = Objects.requireNonNull(sourceName);
>>  +        if(formats.size()==0){
>>  +            throw new IllegalArgumentException("Format 
> required.");
>>  +        }
>>  +        this.formats.addAll(formats);
>>  +    }
>>  +
>>  +
>>  +    /**
>>  +     * Get the underlying resource.
>>  +     *
>>  +     * @return the underlying resource, never null.
>>  +     */
>>  +    public Resource getResource() {
>>  +        return this.resource;
>>  +    }
>>  +
>>  +
>>  +    @Override
>>  +    public String toString() {
>>  +        return "ResourcePropertySourceProvider{" +
>>  +                "resource=" + resource +
>>  +                ", formats=+" + formats +
>>  +                '}';
>>  +    }
>>  +
>>  +    @Override
>>  +    public Collection<PropertySource> getPropertySources() {
>>  +        List<PropertySource> propertySources = new 
> ArrayList<>();
>>  +        for (ConfigurationFormat format : formats) {
>>  +            try {
>>  +                
> propertySources.addAll(format.readConfiguration(sourceName, 
>>  resource));
>>  +            } catch (Exception e) {
>>  +                LOG.info(() -> "Format was not matching: " + 
>>  format + " for resource: " + resource.getName());
>>  +            }
>>  +        }
>>  +        return propertySources;
>>  +    }
>>  +
>>  +}
>> 
>> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
>>  ----------------------------------------------------------------------
>>  diff --git 
>> 
> a/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java 
>> 
> b/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
>>  new file mode 100644
>>  index 0000000..5d289bb
>>  --- /dev/null
>>  +++ 
> b/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
>>  @@ -0,0 +1,53 @@
>>  +/*
>>  + * Licensed to the Apache Software Foundation (ASF) under one
>>  + * or more contributor license agreements.  See the NOTICE file
>>  + * distributed with this work for additional information
>>  + * regarding copyright ownership.  The ASF licenses this file
>>  + * to you under the Apache License, Version 2.0 (the
>>  + * "License"); you may not use this file except in compliance
>>  + * with the License.  You may obtain a copy of the License at
>>  + *
>>  + *  http://www.apache.org/licenses/LICENSE-2.0
>>  + *
>>  + * Unless required by applicable law or agreed to in writing,
>>  + * software distributed under the License is distributed on an
>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>  + * KIND, either express or implied.  See the License for the
>>  + * specific language governing permissions and limitations
>>  + * under the License.
>>  + */
>>  +package org.apache.tamaya.core.formats;
>>  +
>>  +import org.apache.tamaya.core.resources.Resource;
>>  +import org.apache.tamaya.spi.PropertySource;
>>  +
>>  +import java.io.IOException;
>>  +import java.util.Collection;
>>  +
>>  +/**
>>  + * Implementations current this class encapsulate the mechanism how to 
> read a
>>  + * resource including interpreting the format correctly (e.g. xml vs.
>>  + * properties). In most cases file only contains entries of the same 
> priority, 
>>  which would then
>>  + * result in only one {@link PropertySource}. Complex file formats, 
>>  hoiwever, may contain entries
>>  + * of different priorities. In this cases, each ordinal type found must be 
> 
>>  returned as a separate
>>  + * {@link PropertySource} instance.
>>  + */
>>  +@FunctionalInterface
>>  +public interface ConfigurationFormat {
>>  +
>>  +    /**
>>  +     * Reads a list {@link org.apache.tamaya.spi.PropertySource} 
> instances 
>>  from a resource, using this format.
>>  +     * If the configuration format only contains entries of one ordinal 
> type, 
>>  normally only one single
>>  +     * instance of PropertySource is returned. Nevertheless custom formats 
> may 
>>  contain different sections or parts,
>>  +     * where each part maps to a different target rdinal (eg defaults, 
> domain 
>>  config and app config). In the
>>  +     * ladder case multiple PropertySources can be returned, each one with 
> its 
>>  own ordinal and the corresponding
>>  +     * entries.
>>  +     *
>>  +     * @param sourceName name to be used for constructing a useful name 
> for the 
>>  created
>>  +     *                   {@link org.apache.tamaya.spi.PropertySource} 
> 
>>  instances.
>>  +     * @param resource   the configuration resource, not null
>>  +     * @return the corresponding {@link 
>>  org.apache.tamaya.spi.PropertySource} instances, never {@code null}.
>>  +     */
>>  +    Collection<PropertySource> readConfiguration(String sourceName, 
>>  Resource resource) throws IOException;
>>  +
>>  +}
>> 
>> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
>>  ----------------------------------------------------------------------
>>  diff --git 
>>  a/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java 
>>  b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
>>  new file mode 100644
>>  index 0000000..3584f8e
>>  --- /dev/null
>>  +++ 
> b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
>>  @@ -0,0 +1,114 @@
>>  +/*
>>  + * Licensed to the Apache Software Foundation (ASF) under one
>>  + * or more contributor license agreements.  See the NOTICE file
>>  + * distributed with this work for additional information
>>  + * regarding copyright ownership.  The ASF licenses this file
>>  + * to you under the Apache License, Version 2.0 (the
>>  + * "License"); you may not use this file except in compliance
>>  + * with the License.  You may obtain a copy of the License at
>>  + *
>>  + *  http://www.apache.org/licenses/LICENSE-2.0
>>  + *
>>  + * Unless required by applicable law or agreed to in writing,
>>  + * software distributed under the License is distributed on an
>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>  + * KIND, either express or implied.  See the License for the
>>  + * specific language governing permissions and limitations
>>  + * under the License.
>>  + */
>>  +package org.apache.tamaya.core.formats;
>>  +
>>  +import org.apache.tamaya.core.resources.Resource;
>>  +import org.apache.tamaya.spi.PropertySource;
>>  +
>>  +import java.io.InputStream;
>>  +import java.util.ArrayList;
>>  +import java.util.Collection;
>>  +import java.util.Collections;
>>  +import java.util.List;
>>  +import java.util.Map;
>>  +import java.util.Optional;
>>  +import java.util.Properties;
>>  +import java.util.logging.Level;
>>  +import java.util.logging.Logger;
>>  +
>>  +/**
>>  + * Implementation of a {@link 
>>  org.apache.tamaya.core.formats.ConfigurationFormat} for -properties files.
>>  + *
>>  + * @see java.util.Properties#load(java.io.InputStream)
>>  + */
>>  +public class PropertiesFormat implements ConfigurationFormat {
>>  +    /**
>>  +     * The logger.
>>  +     */
>>  +    private final static Logger LOG = 
>>  Logger.getLogger(PropertiesFormat.class.getName());
>>  +
>>  +    /**
>>  +     * The target ordinal.
>>  +     */
>>  +    private int ordinal;
>>  +
>>  +    /**
>>  +     * Creates a new format instance, hereby producing entries with the 
> given 
>>  ordinal, if not overridden by the
>>  +     * configuration itself.
>>  +     * TODO document and implement override feature
>>  +     * @param ordinal the target ordinal.
>>  +     */
>>  +    public PropertiesFormat(int ordinal) {
>>  +        this.ordinal = ordinal;
>>  +    }
>>  +
>>  +    /**
>>  +     * Get the target ordinal, produced by this format.
>>  +     *
>>  +     * @return the target ordinal
>>  +     */
>>  +    public int getOrdinal() {
>>  +        return ordinal;
>>  +    }
>>  +
>>  +    @SuppressWarnings("unchecked")
>>  +    @Override
>>  +    public Collection<PropertySource> readConfiguration(String 
> baseName, 
>>  Resource resource) {
>>  +        final String sourceName = 
>>  (baseName==null?"Properties:":baseName) + resource.getName();
>>  +        if (resource.exists()) {
>>  +            List<PropertySource> propertySources = new 
>>  ArrayList<>();
>>  +            try (InputStream is = resource.getInputStream()) {
>>  +                final Properties p = new Properties();
>>  +                p.load(is);
>>  +                propertySources.add(new PropertySource() {
>>  +                    @Override
>>  +                    public int getOrdinal() {
>>  +                        return ordinal;
>>  +                    }
>>  +
>>  +                    @Override
>>  +                    public String getName() {
>>  +                        return sourceName;
>>  +                    }
>>  +
>>  +                    @Override
>>  +                    public Optional<String> get(String key) {
>>  +                        return Optional.ofNullable(p.getProperty(key));
>>  +                    }
>>  +
>>  +                    @Override
>>  +                    public Map<String, String> getProperties() 
> {
>>  +                        return Map.class.cast(p);
>>  +                    }
>>  +                });
>>  +                return propertySources;
>>  +            } catch (Exception e) {
>>  +                LOG.log(Level.FINEST, e, () -> "Failed to read 
> config 
>>  from resource: " + resource);
>>  +            }
>>  +        }
>>  +        return Collections.emptyList();
>>  +    }
>>  +
>>  +    @Override
>>  +    public String toString() {
>>  +        return "PropertiesFormat{" +
>>  +                "ordinal=" + ordinal +
>>  +                '}';
>>  +    }
>>  +}
>> 
>> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
>>  ----------------------------------------------------------------------
>>  diff --git 
>> 
> a/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java 
>> 
> b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
>>  new file mode 100644
>>  index 0000000..3f77810
>>  --- /dev/null
>>  +++ 
> b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
>>  @@ -0,0 +1,115 @@
>>  +/*
>>  + * Licensed to the Apache Software Foundation (ASF) under one
>>  + * or more contributor license agreements.  See the NOTICE file
>>  + * distributed with this work for additional information
>>  + * regarding copyright ownership.  The ASF licenses this file
>>  + * to you under the Apache License, Version 2.0 (the
>>  + * "License"); you may not use this file except in compliance
>>  + * with the License.  You may obtain a copy of the License at
>>  + *
>>  + *  http://www.apache.org/licenses/LICENSE-2.0
>>  + *
>>  + * Unless required by applicable law or agreed to in writing,
>>  + * software distributed under the License is distributed on an
>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>  + * KIND, either express or implied.  See the License for the
>>  + * specific language governing permissions and limitations
>>  + * under the License.
>>  + */
>>  +package org.apache.tamaya.core.formats;
>>  +
>>  +import org.apache.tamaya.core.resources.Resource;
>>  +import org.apache.tamaya.spi.PropertySource;
>>  +
>>  +import java.io.InputStream;
>>  +import java.util.ArrayList;
>>  +import java.util.Collection;
>>  +import java.util.Collections;
>>  +import java.util.List;
>>  +import java.util.Map;
>>  +import java.util.Optional;
>>  +import java.util.Properties;
>>  +import java.util.logging.Level;
>>  +import java.util.logging.Logger;
>>  +
>>  +/**
>>  + * Implementation of a {@link 
>>  org.apache.tamaya.core.formats.ConfigurationFormat} for xml property
>>  + * files.
>>  + *
>>  + * @see java.util.Properties#loadFromXML(java.io.InputStream)
>>  + */
>>  +public class PropertiesXmlFormat implements ConfigurationFormat {
>>  +    /**
>>  +     * The logger.
>>  +     */
>>  +    private final static Logger LOG = 
>>  Logger.getLogger(PropertiesXmlFormat.class.getName());
>>  +
>>  +    /**
>>  +     * The target ordinal.
>>  +     */
>>  +    private int ordinal;
>>  +
>>  +    /**
>>  +     * Creates a new format instance, producing entries for the given 
> ordinal, 
>>  if not overridden by a
>>  +     * config entry itself.
>>  +     * TODO document and implement override feature
>>  +     * @param ordinal the target ordinal.
>>  +     */
>>  +    public PropertiesXmlFormat(int ordinal) {
>>  +        this.ordinal = ordinal;
>>  +    }
>>  +
>>  +    /**
>>  +     * Get the target ordinal, produced by this format.
>>  +     *
>>  +     * @return the target ordinal
>>  +     */
>>  +    public int getOrdinal() {
>>  +        return ordinal;
>>  +    }
>>  +
>>  +    @SuppressWarnings("unchecked")
>>  +    @Override
>>  +    public Collection<PropertySource> readConfiguration(String 
> baseName, 
>>  Resource resource) {
>>  +        if (resource.exists()) {
>>  +            final String sourceName = 
>>  (baseName==null?"Properties:":baseName) + resource.getName();
>>  +            List<PropertySource> propertySources = new 
>>  ArrayList<>();
>>  +            try (InputStream is = resource.getInputStream()) {
>>  +                final Properties p = new Properties();
>>  +                p.loadFromXML(is);
>>  +                propertySources.add(new PropertySource() {
>>  +                    @Override
>>  +                    public int getOrdinal() {
>>  +                        return ordinal;
>>  +                    }
>>  +
>>  +                    @Override
>>  +                    public String getName() {
>>  +                        return sourceName;
>>  +                    }
>>  +
>>  +                    @Override
>>  +                    public Optional<String> get(String key) {
>>  +                        return Optional.ofNullable(p.getProperty(key));
>>  +                    }
>>  +
>>  +                    @Override
>>  +                    public Map<String, String> getProperties() 
> {
>>  +                        return Map.class.cast(p);
>>  +                    }
>>  +                });
>>  +                return propertySources;
>>  +            } catch (Exception e) {
>>  +                LOG.log(Level.FINEST, e, () -> "Failed to read 
> config 
>>  from resource: " + resource);
>>  +            }
>>  +        }
>>  +        return Collections.emptyList();
>>  +    }
>>  +
>>  +    @Override
>>  +    public String toString() {
>>  +        return "PropertiesXmlFormat{" +
>>  +                "ordinal=" + ordinal +
>>  +                '}';
>>  +    }
>>  +}
>> 
>> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
>>  ----------------------------------------------------------------------
>>  diff --git 
>> 
> a/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java 
>> 
> b/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
>>  index 0a39b7d..3769e27 100644
>>  --- 
>> 
> a/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
>>  +++ 
>> 
> b/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
>>  @@ -22,6 +22,7 @@ import org.apache.tamaya.ConfigException;
>>  import org.apache.tamaya.Configuration;
>>  import org.apache.tamaya.spi.ConfigurationContext;
>>  import org.apache.tamaya.spi.PropertyConverter;
>>  +import org.apache.tamaya.spi.PropertyFilter;
>>  import org.apache.tamaya.spi.PropertySource;
>>  import org.apache.tamaya.spi.ServiceContext;
>> 
>>  @@ -33,6 +34,7 @@ import java.util.Map;
>>  import java.util.Optional;
>>  import java.util.logging.Level;
>>  import java.util.logging.Logger;
>>  +import java.util.stream.Collectors;
>> 
>>  /**
>>    * Implementation of the Configuration API. This class uses the current 
>>  {@link ConfigurationContext} to evaluate the
>>  @@ -56,13 +58,21 @@ public class DefaultConfiguration implements 
> Configuration 
>>  {
>>       @Override
>>       public Optional<String> get(String key) {
>>           List<PropertySource> propertySources = 
>> 
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertySources();
>>  +        String unfilteredValue = null;
>>           for (PropertySource propertySource : propertySources) {
>>               Optional<String> value = propertySource.get(key);
>>               if (value.isPresent()) {
>>  -                return value;
>>  +                unfilteredValue = value.get();
>>  +                break;
>>               }
>>           }
>>  -        return Optional.empty();
>>  +        // Apply filters to values, prevent values filtered to null!
>>  +        for(PropertyFilter filter:
>>  +                
>> 
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyFilters()){
>>  +            unfilteredValue = filter.filterProperty(key, unfilteredValue,
>>  +                    (String k) -> 
> key.equals(k)?null:get(k).orElse(null));
>>  +        }
>>  +        return Optional.ofNullable(unfilteredValue);
>>       }
>> 
>>       @Override
>>  @@ -83,7 +93,15 @@ public class DefaultConfiguration implements 
> Configuration 
>>  {
>>                   LOG.log(Level.SEVERE, "Error adding properties from 
>>  PropertySource: " + propertySource +", ignoring 
> PropertySource.", 
>>  e);
>>               }
>>           }
>>  -        return result;
>>  +        // Apply filters to values, prevent values filtered to null!
>>  +        for(PropertyFilter filter:
>>  +                
>> 
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyFilters()){
>>  +            result.replaceAll((k,v) -> filter.filterProperty(k, v,
>>  +                    (String k2) -> 
> k2.equals(k)?null:get(k2).orElse(null)));
>>  +        }
>>  +        // Remove null values
>>  +        return result.entrySet().parallelStream().filter((e) -> 
>>  e.getValue()!=null).collect(
>>  +                Collectors.toMap((e) -> e.getKey(), (e) -> 
>>  e.getValue()));
>>       }
>> 
>>       /**
>>  @@ -101,7 +119,8 @@ public class DefaultConfiguration implements 
> Configuration 
>>  {
>>       public <T> Optional<T> get(String key, Class<T> 
> type) 
>>  {
>>           Optional<String> value = get(key);
>>           if (value.isPresent()) {
>>  -            List<PropertyConverter<T>> converters = 
>> 
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyConverters(type);
>>  +            List<PropertyConverter<T>> converters = 
>>  ServiceContext.getInstance().getService(ConfigurationContext.class)
>>  +                    .get().getPropertyConverters(type);
>>               for (PropertyConverter<T> converter : converters) {
>>                   try {
>>                       T t = converter.convert(value.get());
>> 
>> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
>>  ----------------------------------------------------------------------
>>  diff --git 
>> 
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java 
> 
>> 
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
>>  new file mode 100644
>>  index 0000000..21806cd
>>  --- /dev/null
>>  +++ 
>> 
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
>>  @@ -0,0 +1,178 @@
>>  +/*
>>  + * Licensed to the Apache Software Foundation (ASF) under one
>>  + * or more contributor license agreements.  See the NOTICE file
>>  + * distributed with this work for additional information
>>  + * regarding copyright ownership.  The ASF licenses this file
>>  + * to you under the Apache License, Version 2.0 (the
>>  + * "License"); you may not use this file except in compliance
>>  + * with the License.  You may obtain a copy of the License at
>>  + *
>>  + *  http://www.apache.org/licenses/LICENSE-2.0
>>  + *
>>  + * Unless required by applicable law or agreed to in writing,
>>  + * software distributed under the License is distributed on an
>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>  + * KIND, either express or implied.  See the License for the
>>  + * specific language governing permissions and limitations
>>  + * under the License.
>>  + */
>>  +package org.apache.tamaya.core.internal.resource;
>>  +
>>  +import org.apache.tamaya.core.resources.Resource;
>>  +
>>  +import java.io.IOException;
>>  +import java.io.InputStream;
>>  +import java.net.URI;
>>  +import java.net.URISyntaxException;
>>  +import java.net.URL;
>>  +import java.util.Objects;
>>  +
>>  +/**
>>  + * Implementation of {@link Resource} to be loaded from the 
> classpath.
>>  + */
>>  +public class ClassPathResource implements Resource {
>>  +
>>  +    private final String path;
>>  +
>>  +    private ClassLoader classLoader;
>>  +
>>  +
>>  +    /**
>>  +     * Create a new resource using the current context class loader.
>>  +     *
>>  +     * @param path the resource path, not null
>>  +     * @see java.lang.ClassLoader#getResourceAsStream(String)
>>  +     */
>>  +    public ClassPathResource(String path) {
>>  +        this(path, (ClassLoader) null);
>>  +    }
>>  +
>>  +    /**
>>  +     * Create a new resource using the given class loader.
>>  +     *
>>  +     * @param path        the resource path, not null
>>  +     * @param classLoader the class loader to load the resource with,
>>  +     *                    or {@code null} for the current context 
> class 
>>  loader
>>  +     * @see ClassLoader#getResourceAsStream(String)
>>  +     */
>>  +    public ClassPathResource(String path, ClassLoader classLoader) {
>>  +        Objects.requireNonNull(path, "Path null");
>>  +        if (path.startsWith("/")) {
>>  +            path = path.substring(1);
>>  +        }
>>  +        this.path = path.trim();
>>  +        if(classLoader==null){
>>  +            classLoader = Thread.currentThread().getContextClassLoader();
>>  +        }
>>  +        if(classLoader==null){
>>  +            classLoader = getClass().getClassLoader();
>>  +        }
>>  +        this.classLoader = classLoader;
>>  +    }
>>  +
>>  +    /**
>>  +     * @return the path for this resource.
>>  +     */
>>  +    public final String getPath() {
>>  +        return this.path;
>>  +    }
>>  +
>>  +    /**
>>  +     * @return the ClassLoader that this resource will be accessed from.
>>  +     */
>>  +    public final ClassLoader getClassLoader() {
>>  +        return this.classLoader;
>>  +    }
>>  +
>>  +
>>  +    /**
>>  +     * Checks if the given resource is resolvable from the configured 
>>  classloader.
>>  +     *
>>  +     * @see java.lang.ClassLoader#getResource(String)
>>  +     */
>>  +    @Override
>>  +    public boolean exists() {
>>  +        return (resolveURL() != null);
>>  +    }
>>  +
>>  +    /**
>>  +     * Resolves a URL for the underlying class path resource.
>>  +     *
>>  +     * @return the resolved URL, or {@code null}
>>  +     */
>>  +    protected URL resolveURL() {
>>  +        return this.classLoader.getResource(this.path);
>>  +    }
>>  +
>>  +    /**
>>  +     * This implementation opens an InputStream for the given class path 
>>  resource.
>>  +     *
>>  +     * @see java.lang.ClassLoader#getResourceAsStream(String)
>>  +     * @see java.lang.Class#getResourceAsStream(String)
>>  +     */
>>  +    @Override
>>  +    public InputStream getInputStream() throws IOException {
>>  +        InputStream is = this.classLoader.getResourceAsStream(this.path);
>>  +        if (is == null) {
>>  +            throw new IOException(getName() + " does not 
> exist");
>>  +        }
>>  +        return is;
>>  +    }
>>  +
>>  +    @Override
>>  +    public URI toURI() throws IOException {
>>  +        try {
>>  +            return resolveURL().toURI();
>>  +        } catch (URISyntaxException e) {
>>  +            throw new IOException(e);
>>  +        }
>>  +    }
>>  +
>>  +    @Override
>>  +    public long lastModified() throws IOException {
>>  +        return 0;
>>  +    }
>>  +
>>  +    /**
>>  +     * This implementation returns the name current the file that this 
> class 
>>  path
>>  +     * resource refers to.
>>  +     */
>>  +    @Override
>>  +    public String getName() {
>>  +        return "classpath:"+path;
>>  +    }
>>  +
>>  +    /**
>>  +     * This implementation returns a description that includes the class 
> path 
>>  location.
>>  +     */
>>  +    @Override
>>  +    public String toString() {
>>  +        return "ClassPathResource[" + path + ']';
>>  +    }
>>  +
>>  +    /**
>>  +     * This implementation compares the underlying class path locations.
>>  +     */
>>  +    @Override
>>  +    public boolean equals(Object obj) {
>>  +        if (obj == this) {
>>  +            return true;
>>  +        }
>>  +        if (obj instanceof ClassPathResource) {
>>  +            ClassPathResource otherRes = (ClassPathResource) obj;
>>  +            return (this.path.equals(otherRes.path) &&
>>  +                    Objects.equals(this.classLoader, 
> otherRes.classLoader));
>>  +        }
>>  +        return false;
>>  +    }
>>  +
>>  +    /**
>>  +     * This implementation returns the hash code current the underlying
>>  +     * class path location.
>>  +     */
>>  +    @Override
>>  +    public int hashCode() {
>>  +        return getName().hashCode();
>>  +    }
>>  +
>>  +}
>> 
>> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
>>  ----------------------------------------------------------------------
>>  diff --git 
>> 
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java 
> 
>> 
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
>>  new file mode 100644
>>  index 0000000..eb56c1d
>>  --- /dev/null
>>  +++ 
>> 
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
>>  @@ -0,0 +1,93 @@
>>  +/*
>>  + * Licensed to the Apache Software Foundation (ASF) under one
>>  + * or more contributor license agreements.  See the NOTICE file
>>  + * distributed with this work for additional information
>>  + * regarding copyright ownership.  The ASF licenses this file
>>  + * to you under the Apache License, Version 2.0 (the
>>  + * "License"); you may not use this file except in compliance
>>  + * with the License.  You may obtain a copy of the License at
>>  + *
>>  + *  http://www.apache.org/licenses/LICENSE-2.0
>>  + *
>>  + * Unless required by applicable law or agreed to in writing,
>>  + * software distributed under the License is distributed on an
>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>  + * KIND, either express or implied.  See the License for the
>>  + * specific language governing permissions and limitations
>>  + * under the License.
>>  + */
>>  +package org.apache.tamaya.core.internal.resource;
>>  +
>>  +import org.apache.tamaya.core.resources.Resource;
>>  +import org.apache.tamaya.core.resources.ResourceLoader;
>>  +
>>  +import javax.annotation.Priority;
>>  +import java.io.File;
>>  +import java.net.URL;
>>  +import java.util.ArrayList;
>>  +import java.util.Collection;
>>  +import java.util.Enumeration;
>>  +import java.util.List;
>>  +import java.util.logging.Logger;
>>  +
>>  +/**
>>  + * Simple default implementation of the resource loader, which does only 
>>  support direct references to files.
>>  + */
>>  +@Priority(0)
>>  +public class DefaultResourceLoader implements ResourceLoader {
>>  +
>>  +    private static final Logger LOG = 
>>  Logger.getLogger(DefaultResourceLoader.class.getName());
>>  +
>>  +    @Override
>>  +    public List<Resource> getResources(ClassLoader classLoader, 
>>  Collection<String> expressions) {
>>  +        List<Resource> resources = new ArrayList<>();
>>  +        for (String expression : expressions) {
>>  +            if (tryClassPath(classLoader, expression, resources) || 
>>  tryFile(expression, resources) ||
>>  +                    tryURL(expression, resources)) {
>>  +                continue;
>>  +            }
>>  +            LOG.warning("Failed to resolve resource: " + 
> expression);
>>  +        }
>>  +        return resources;
>>  +    }
>>  +
>>  +    private boolean tryClassPath(ClassLoader classLoader, String 
> expression, 
>>  List<Resource> resources) {
>>  +        try {
>>  +            Enumeration<URL> urls = 
> classLoader.getResources(expression);
>>  +            while (urls.hasMoreElements()) {
>>  +                URL url = urls.nextElement();
>>  +                resources.add(new URLResource(url));
>>  +            }
>>  +            return !resources.isEmpty();
>>  +        } catch (Exception e) {
>>  +            LOG.finest(() -> "Failed to load resource from CP: 
> " + 
>>  expression);
>>  +        }
>>  +        return false;
>>  +    }
>>  +
>>  +    private boolean tryFile(String expression, List<Resource> 
> resources) 
>>  {
>>  +        try {
>>  +            File file = new File(expression);
>>  +            if (file.exists()) {
>>  +                resources.add(new FileResource(file));
>>  +                return true;
>>  +            }
>>  +        } catch (Exception e) {
>>  +            LOG.finest(() -> "Failed to load resource from file: 
> " 
>>  + expression);
>>  +        }
>>  +        return false;
>>  +    }
>>  +
>>  +    private boolean tryURL(String expression, List<Resource> 
> resources) 
>>  {
>>  +        try {
>>  +            URL url = new URL(expression);
>>  +            resources.add(new URLResource(url));
>>  +            return true;
>>  +        } catch (Exception e) {
>>  +            LOG.finest(() -> "Failed to load resource from file: 
> " 
>>  + expression);
>>  +        }
>>  +        return false;
>>  +
>>  +    }
>>  +
>>  +}
>> 
>> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
>>  ----------------------------------------------------------------------
>>  diff --git 
>> 
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java 
>> 
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
>>  new file mode 100644
>>  index 0000000..e0096e5
>>  --- /dev/null
>>  +++ 
>> 
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
>>  @@ -0,0 +1,162 @@
>>  +/*
>>  + * Licensed to the Apache Software Foundation (ASF) under one
>>  + * or more contributor license agreements.  See the NOTICE file
>>  + * distributed with this work for additional information
>>  + * regarding copyright ownership.  The ASF licenses this file
>>  + * to you under the Apache License, Version 2.0 (the
>>  + * "License"); you may not use this file except in compliance
>>  + * with the License.  You may obtain a copy of the License at
>>  + *
>>  + *  http://www.apache.org/licenses/LICENSE-2.0
>>  + *
>>  + * Unless required by applicable law or agreed to in writing,
>>  + * software distributed under the License is distributed on an
>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>  + * KIND, either express or implied.  See the License for the
>>  + * specific language governing permissions and limitations
>>  + * under the License.
>>  + */
>>  +package org.apache.tamaya.core.internal.resource;
>>  +
>>  +import org.apache.tamaya.core.resources.Resource;
>>  +
>>  +import java.io.File;
>>  +import java.io.FileInputStream;
>>  +import java.io.IOException;
>>  +import java.io.InputStream;
>>  +import java.net.URI;
>>  +import java.util.Objects;
>>  +
>>  +/**
>>  + * Implementation of {@link 
> org.apache.tamaya.core.resources.Resource} to 
>>  be loaded from a file.
>>  + * @see java.io.File
>>  + */
>>  +public class FileResource implements Resource {
>>  +
>>  +    private final File file;
>>  +
>>  +    /**
>>  +     * Creates a new instance.
>>  +     *
>>  +     * @param file a File, not null.
>>  +     */
>>  +    public FileResource(File file) {
>>  +        this.file = Objects.requireNonNull(file, "File must not be 
>>  null");
>>  +    }
>>  +
>>  +    /**
>>  +     * Crreates a new instance.
>>  +     *
>>  +     * @param filePath a file path
>>  +     */
>>  +    public FileResource(String filePath) {
>>  +        Objects.requireNonNull(filePath, "Path must not be 
> null");
>>  +        this.file = new File(filePath);
>>  +    }
>>  +
>>  +
>>  +    /**
>>  +     * Get the file path for this resource.
>>  +     */
>>  +    public final String getPath() {
>>  +        return this.file.getPath();
>>  +    }
>>  +
>>  +
>>  +    /**
>>  +     * This implementation returns whether the underlying file exists.
>>  +     *
>>  +     * @see java.io.File#exists()
>>  +     */
>>  +    @Override
>>  +    public boolean exists() {
>>  +        return this.file.exists();
>>  +    }
>>  +
>>  +    /**
>>  +     * This implementation checks whether the underlying file is marked as 
> 
>>  readable
>>  +     * (and corresponds to an actual file with content, not to a 
> directory).
>>  +     *
>>  +     * @see java.io.File#canRead()
>>  +     * @see java.io.File#isDirectory()
>>  +     */
>>  +    @Override
>>  +    public boolean isAccessible() {
>>  +        return (this.file.canRead() && !this.file.isDirectory());
>>  +    }
>>  +
>>  +    /**
>>  +     * This implementation opens a FileInputStream for the underlying 
> file.
>>  +     *
>>  +     * @see java.io.FileInputStream
>>  +     */
>>  +    @Override
>>  +    public InputStream getInputStream() throws IOException {
>>  +        return new FileInputStream(this.file);
>>  +    }
>>  +
>>  +    /**
>>  +     * This implementation returns a URI for the underlying file.
>>  +     *
>>  +     * @see java.io.File#toURI()
>>  +     */
>>  +    @Override
>>  +    public URI toURI() throws IOException {
>>  +        return this.file.toURI();
>>  +    }
>>  +
>>  +    /**
>>  +     * Returns the underlying File's length.
>>  +     */
>>  +    @Override
>>  +    public long length() throws IOException {
>>  +        return this.file.length();
>>  +    }
>>  +
>>  +    @Override
>>  +    public long lastModified() throws IOException {
>>  +        return file.lastModified();
>>  +    }
>>  +
>>  +    /**
>>  +     * Returns the name of the current file.
>>  +     *
>>  +     * @see java.io.File#getName()
>>  +     */
>>  +    @Override
>>  +    public String getName() {
>>  +        return this.file.getName();
>>  +    }
>>  +
>>  +    /**
>>  +     * Returns a description that includes the absolute
>>  +     * path of the current file.
>>  +     *
>>  +     * @see java.io.File#getAbsolutePath()
>>  +     */
>>  +    @Override
>>  +    public String toString() {
>>  +        return "File [" + this.file.getAbsolutePath() + 
>>  "]";
>>  +    }
>>  +
>>  +
>>  +    // implementation current WritableResource
>>  +
>>  +    /**
>>  +     * Compares the underlying Files.
>>  +     */
>>  +    @Override
>>  +    public boolean equals(Object obj) {
>>  +        return (obj == this ||
>>  +                (obj instanceof FileResource && 
>>  this.file.equals(((FileResource) obj).file)));
>>  +    }
>>  +
>>  +    /**
>>  +     * Returns hash code current the underlying File reference.
>>  +     */
>>  +    @Override
>>  +    public int hashCode() {
>>  +        return this.file.hashCode();
>>  +    }
>>  +
>>  +}
>> 
>> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
>>  ----------------------------------------------------------------------
>>  diff --git 
>> 
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java 
> 
>> 
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
>>  new file mode 100644
>>  index 0000000..09510b4
>>  --- /dev/null
>>  +++ 
>> 
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
>>  @@ -0,0 +1,117 @@
>>  +/*
>>  + * Licensed to the Apache Software Foundation (ASF) under one
>>  + * or more contributor license agreements.  See the NOTICE file
>>  + * distributed with this work for additional information
>>  + * regarding copyright ownership.  The ASF licenses this file
>>  + * to you under the Apache License, Version 2.0 (the
>>  + * "License"); you may not use this file except in compliance
>>  + * with the License.  You may obtain a copy of the License at
>>  + *
>>  + *  http://www.apache.org/licenses/LICENSE-2.0
>>  + *
>>  + * Unless required by applicable law or agreed to in writing,
>>  + * software distributed under the License is distributed on an
>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>  + * KIND, either express or implied.  See the License for the
>>  + * specific language governing permissions and limitations
>>  + * under the License.
>>  + */
>>  +package org.apache.tamaya.core.internal.resource;
>>  +
>>  +import org.apache.tamaya.core.resources.Resource;
>>  +
>>  +import java.io.IOException;
>>  +import java.io.InputStream;
>>  +import java.net.URI;
>>  +import java.util.Objects;
>>  +
>>  +/**
>>  + * Simple Resource encapsulating an InputStream.
>>  + */
>>  +public class InputStreamResource implements Resource {
>>  +
>>  +    /** The InputStream. */
>>  +    private final InputStream inputStream;
>>  +    /** The read flag. */
>>  +    private boolean read = false;
>>  +    /** The name of the resource. */
>>  +    private String name;
>>  +
>>  +
>>  +    /**
>>  +     * Create a new InputStreamResource.
>>  +     *
>>  +     * @param inputStream the InputStream to use
>>  +     */
>>  +    public InputStreamResource(InputStream inputStream) {
>>  +        this(inputStream, "InputStream:");
>>  +    }
>>  +
>>  +    /**
>>  +     * Create a new InputStreamResource.
>>  +     *
>>  +     * @param inputStream the InputStream to use
>>  +     * @param name where the InputStream comes from
>>  +     */
>>  +    public InputStreamResource(InputStream inputStream, String name) 
> {
>>  +        this.inputStream = Objects.requireNonNull(inputStream);
>>  +        this.name = (name != null ? name : "InputStream");
>>  +    }
>>  +
>>  +
>>  +    /**
>>  +     * This implementation always returns {@code true}.
>>  +     */
>>  +    @Override
>>  +    public boolean exists() {
>>  +        return true;
>>  +    }
>>  +
>>  +    @Override
>>  +    public URI toURI() throws IOException {
>>  +        throw new IOException("URI not available.");
>>  +    }
>>  +
>>  +    @Override
>>  +    public long lastModified() throws IOException {
>>  +        throw new IOException("lastModified not available.");
>>  +    }
>>  +
>>  +    /**
>>  +     * Accesses the input stream. Hereby the input stream can only 
> accessed 
>>  once.
>>  +     */
>>  +    @Override
>>  +    public InputStream getInputStream() throws IOException {
>>  +        if (this.read) {
>>  +            throw new IllegalStateException("InputStream can only be 
> read 
>>  once!");
>>  +        }
>>  +        this.read = true;
>>  +        return this.inputStream;
>>  +    }
>>  +
>>  +    /**
>>  +     * This implementation returns the passed-in description, if any.
>>  +     */
>>  +    public String toString() {
>>  +        return this.name != null ? this.name : super.toString();
>>  +    }
>>  +
>>  +
>>  +    /**
>>  +     * Compares the underlying InputStream.
>>  +     */
>>  +    @Override
>>  +    public boolean equals(Object obj) {
>>  +        return (obj == this ||
>>  +                (obj instanceof InputStreamResource && 
>>  ((InputStreamResource) obj).inputStream.equals(this.inputStream)));
>>  +    }
>>  +
>>  +    /**
>>  +     * This implementation returns the hash code current the underlying 
>>  InputStream.
>>  +     */
>>  +    @Override
>>  +    public int hashCode() {
>>  +        return this.inputStream.hashCode();
>>  +    }
>>  +
>>  +}
>> 
>> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
>>  ----------------------------------------------------------------------
>>  diff --git 
>> 
> a/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java 
>> 
> b/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
>>  new file mode 100644
>>  index 0000000..4da6c53
>>  --- /dev/null
>>  +++ 
>> 
> b/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
>>  @@ -0,0 +1,37 @@
>>  +/*
>>  + * Licensed to the Apache Software Foundation (ASF) under one
>>  + * or more contributor license agreements.  See the NOTICE file
>>  + * distributed with this work for additional information
>>  + * regarding copyright ownership.  The ASF licenses this file
>>  + * to you under the Apache License, Version 2.0 (the
>>  + * "License"); you may not use this file except in compliance
>>  + * with the License.  You may obtain a copy of the License at
>>  + *
>>  + *  http://www.apache.org/licenses/LICENSE-2.0
>>  + *
>>  + * Unless required by applicable law or agreed to in writing,
>>  + * software distributed under the License is distributed on an
>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>  + * KIND, either express or implied.  See the License for the
>>  + * specific language governing permissions and limitations
>>  + * under the License.
>>  + */
>>  +package org.apache.tamaya.core.resources;
>>  +
>>  +import java.io.IOException;
>>  +import java.io.InputStream;
>>  +
>>  +/**
>>  + * Simple interface for a component that provides data based on an 
> InputStream.
>>  + */
>>  +@FunctionalInterface
>>  +public interface InputStreamSupplier {
>>  +
>>  +    /**
>>  +     * Access the input stream.
>>  +     * @return the input stream for use.
>>  +     * @throws IOException i the input stream could not be obtained.
>>  +     */
>>  +    InputStream getInputStream() throws IOException;
>>  +
>>  +}
>> 
>> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
>>  ----------------------------------------------------------------------
>>  diff --git 
> a/core/src/main/java/org/apache/tamaya/core/resources/Resource.java 
>>  b/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
>>  new file mode 100644
>>  index 0000000..31c679d
>>  --- /dev/null
>>  +++ b/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
>>  @@ -0,0 +1,115 @@
>>  +/*
>>  + * Licensed to the Apache Software Foundation (ASF) under one
>>  + * or more contributor license agreements.  See the NOTICE file
>>  + * distributed with this work for additional information
>>  + * regarding copyright ownership.  The ASF licenses this file
>>  + * to you under the Apache License, Version 2.0 (the
>>  + * "License"); you may not use this file except in compliance
>>  + * with the License.  You may obtain a copy of the License at
>>  + *
>>  + *  http://www.apache.org/licenses/LICENSE-2.0
>>  + *
>>  + * Unless required by applicable law or agreed to in writing,
>>  + * software distributed under the License is distributed on an
>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>  + * KIND, either express or implied.  See the License for the
>>  + * specific language governing permissions and limitations
>>  + * under the License.
>>  + */
>>  +package org.apache.tamaya.core.resources;
>>  +
>>  +import java.io.File;
>>  +import java.io.IOException;
>>  +import java.io.InputStream;
>>  +import java.net.URI;
>>  +import java.net.URL;
>>  +import java.util.Objects;
>>  +
>>  +/**
>>  + * Interface for an abstract resource. The effective resource 
> implementation 
>>  can be completely arbitrary.
>>  + * By default files, classpath resources and URLs are supported, but 
> alternate 
>>  implementations are possible.
>>  + *
>>  + * @see #getInputStream()
>>  + * @see #toURI()
>>  + */
>>  +public interface Resource extends InputStreamSupplier {
>>  +
>>  +    /**
>>  +     * Return whether this resource actually exists. Depending on the 
> resource 
>>  this can delegate to
>>  +     * {@link java.io.File#exists()} or whatever may be appropriate 
> to 
>>  check accessibility of the resource.
>>  +     */
>>  +    default boolean exists() {
>>  +        // Try to open a file first, if that fails try to open the 
> stream...
>>  +        try {
>>  +            return new File(toURI()).exists();
>>  +        } catch (IOException ex) {
>>  +            // Fallback
>>  +            try {
>>  +                InputStream is = getInputStream();
>>  +                is.close();
>>  +                return true;
>>  +            } catch (Exception e) {
>>  +                // ignore, just return false for non existing
>>  +                return false;
>>  +            }
>>  +        }
>>  +    }
>>  +
>>  +    /**
>>  +     * Checks whether the resource is accessible, meaning {@link 
>>  #getInputStream()} should return a InputStream for reading the
>>  +     * resource's content.
>>  +     *
>>  +     * @see #getInputStream()
>>  +     */
>>  +    default boolean isAccessible() {
>>  +        return true;
>>  +    }
>>  +
>>  +    /**
>>  +     * Returns the resource as an URI.
>>  +     *
>>  +     * @throws IOException if the resource cannot be resolved as URI.
>>  +     */
>>  +    URI toURI() throws IOException;
>>  +
>>  +    /**
>>  +     * Determines the length for this resource.
>>  +     *
>>  +     * @throws IOException if the resource is not readable.
>>  +     */
>>  +    default long length() throws IOException {
>>  +        try(InputStream is = this.getInputStream();) {
>>  +            Objects.requireNonNull(is, "resource not 
> available");
>>  +            long length = 0;
>>  +            byte[] buf = new byte[256];
>>  +            int bytesRead;
>>  +            while ((bytesRead = is.read(buf)) > 0) {
>>  +                length += bytesRead;
>>  +            }
>>  +            return length;
>>  +        }
>>  +    }
>>  +
>>  +    /**
>>  +     * Determine the last-modified timestamp for a resource, as UTC ms 
>>  timestamp
>>  +     *
>>  +     * @throws IOException if the resource is not accessible.
>>  +     */
>>  +    default long lastModified() throws IOException{
>>  +        return new File(toURI()).lastModified();
>>  +    }
>>  +
>>  +    /**
>>  +     * Get a name for the resource. The name should be identifying the 
> resource 
>>  and also
>>  +     * never change, so it must be eligible for hashcode/equals 
>>  implementations.
>>  +     */
>>  +    default String getName() {
>>  +        try {
>>  +            return toURI().toString();
>>  +        } catch (Exception e) {
>>  +            return toString();
>>  +        }
>>  +    }
>>  +
>>  +
>>  +}
>>  \ No newline at end of file
>> 
>> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
>>  ----------------------------------------------------------------------
>>  diff --git 
>>  a/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java 
>>  b/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
>>  new file mode 100644
>>  index 0000000..5aff10a
>>  --- /dev/null
>>  +++ 
> b/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
>>  @@ -0,0 +1,91 @@
>>  +/*
>>  + * Licensed to the Apache Software Foundation (ASF) under one
>>  + * or more contributor license agreements.  See the NOTICE file
>>  + * distributed with this work for additional information
>>  + * regarding copyright ownership.  The ASF licenses this file
>>  + * to you under the Apache License, Version 2.0 (the
>>  + * "License"); you may not use this file except in compliance
>>  + * with the License.  You may obtain a copy of the License at
>>  + *
>>  + *  http://www.apache.org/licenses/LICENSE-2.0
>>  + *
>>  + * Unless required by applicable law or agreed to in writing,
>>  + * software distributed under the License is distributed on an
>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>  + * KIND, either express or implied.  See the License for the
>>  + * specific language governing permissions and limitations
>>  + * under the License.
>>  + */
>>  +package org.apache.tamaya.core.resources;
>>  +
>>  +import java.util.Arrays;
>>  +import java.util.Collection;
>>  +import java.util.List;
>>  +
>>  +/**
>>  + * Interface to be implemented by modules. By default only direct 
> file/resource 
>>  resolution is supported, whereas
>>  + * extension modules may add functionality to perform ant styled pattern 
>>  resolution of resources.
>>  + */
>>  +public interface ResourceLoader {
>>  +
>>  +    /**
>>  +     * Resolves resource expressions to a list of {@link 
>>  org.apache.tamaya.core.resources.Resource}s. Hereby
>>  +     * the ordering of resources matches the input of the resolved 
> expressions. 
>>  Nevertheless be aware that
>>  +     * there is no determined ordering of resources located within a 
>>  classloader.
>>  +     *
>>  +     * @param expressions the expressions to be resolved, not empty.
>>  +     * @return the corresponding collection of current {@link 
>>  org.apache.tamaya.core.resources.Resource}s found, never
>>  +     * null.
>>  +     * .
>>  +     */
>>  +    default Collection<Resource> 
> getResources(Collection<String> 
>>  expressions) {
>>  +        ClassLoader cl = Thread.currentThread().getContextClassLoader();
>>  +        if (cl == null) {
>>  +            cl = getClass().getClassLoader();
>>  +        }
>>  +        return getResources(cl, expressions);
>>  +    }
>>  +
>>  +    /**
>>  +     * Resolves resource expressions to a list of {@link 
>>  org.apache.tamaya.core.resources.Resource}s. Hereby
>>  +     * the ordering of resources matches the input of the resolved 
> expressions. 
>>  Nevertheless be aware that
>>  +     * there is no determined ordering of resources located within a 
>>  classloader.
>>  +     *
>>  +     * @param expressions the expressions to be resolved, not empty.
>>  +     * @return the corresponding collection of current {@link 
>>  org.apache.tamaya.core.resources.Resource}s found, never
>>  +     * null.
>>  +     * .
>>  +     */
>>  +    default Collection<Resource> getResources(String... expressions) 
> 
>>  {
>>  +        return getResources(Arrays.asList(expressions));
>>  +    }
>>  +
>>  +    /**
>>  +     * Resolves resource expressions to a list of {@link 
>>  org.apache.tamaya.core.resources.Resource}s, considerubg
>>  +     * the given classloader for classloader dependent resources. Hereby
>>  +     * the ordering of resources matches the input of the resolved 
> expressions. 
>>  Nevertheless be aware that
>>  +     * there is no determined ordering of resources located within a 
>>  classloader.
>>  +     *
>>  +     * @param expressions the expressions to be resolved, not empty.
>>  +     * @return the corresponding collection of current {@link 
>>  org.apache.tamaya.core.resources.Resource}s found, never
>>  +     * null.
>>  +     * .
>>  +     */
>>  +    default Collection<Resource> getResources(ClassLoader 
> classLoader, 
>>  String... expressions){
>>  +        return getResources(classLoader, Arrays.asList(expressions));
>>  +    }
>>  +
>>  +    /**
>>  +     * Resolves resource expressions to a list of {@link 
>>  org.apache.tamaya.core.resources.Resource}s, considerubg
>>  +     * the given classloader for classloader dependent resources. Hereby
>>  +     * the ordering of resources matches the input of the resolved 
> expressions. 
>>  Nevertheless be aware that
>>  +     * there is no determined ordering of resources located within a 
>>  classloader.
>>  +     *
>>  +     * @param expressions the expressions to be resolved, not empty.
>>  +     * @return the corresponding collection of current {@link 
>>  org.apache.tamaya.core.resources.Resource}s found, never
>>  +     * null.
>>  +     * .
>>  +     */
>>  +    Collection<Resource> getResources(ClassLoader classLoader, 
>>  Collection<String> expressions);
>>  +
>>  +}
>> 
>> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
>>  ----------------------------------------------------------------------
>>  diff --git 
> a/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java 
>>  b/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
>>  index be1eadb..9c7b894 100644
>>  --- a/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
>>  +++ b/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
>>  @@ -41,6 +41,12 @@ public class ConfigurationTest {
>>           assertEquals("Lukas", 
>>  Configuration.current().get("name3").get());  // oderridden 
> default
>>           assertEquals("Sereina", 
>>  Configuration.current().get("name4").get()); // final only
>>           assertEquals("Benjamin", 
>>  Configuration.current().get("name5").get()); // final only
>>  +
>>  +        System.out.println("name : " + 
>>  Configuration.current().get("name").get());
>>  +        System.out.println("name2: " + 
>>  Configuration.current().get("name2").get());
>>  +        System.out.println("name3: " + 
>>  Configuration.current().get("name3").get());
>>  +        System.out.println("name4: " + 
>>  Configuration.current().get("name4").get());
>>  +        System.out.println("name5: " + 
>>  Configuration.current().get("name5").get());
>>       }
>> 
>> 
>> 
>> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
>>  ----------------------------------------------------------------------
>>  diff --git 
>> 
> a/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java 
> 
>> 
> b/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
>>  deleted file mode 100644
>>  index 51cc2dc..0000000
>>  --- 
>> 
> a/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
>>  +++ /dev/null
>>  @@ -1,70 +0,0 @@
>>  -/*
>>  - * Licensed to the Apache Software Foundation (ASF) under one
>>  - * or more contributor license agreements.  See the NOTICE file
>>  - * distributed with this work for additional information
>>  - * regarding copyright ownership.  The ASF licenses this file
>>  - * to you under the Apache License, Version 2.0 (the
>>  - * "License"); you may not use this file except in compliance
>>  - * with the License.  You may obtain a copy of the License at
>>  - *
>>  - * http://www.apache.org/licenses/LICENSE-2.0
>>  - *
>>  - * Unless required by applicable law or agreed to in writing,
>>  - * software distributed under the License is distributed on an
>>  - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>  - * KIND, either express or implied.  See the License for the
>>  - * specific language governing permissions and limitations
>>  - * under the License.
>>  - */
>>  -package org.apache.tamaya.core.test.propertysource;
>>  -
>>  -import org.apache.tamaya.core.propertysource.DefaultOrdinal;
>>  -import org.apache.tamaya.core.propertysource.EnvironmentPropertySource;
>>  -import org.junit.Assert;
>>  -import org.junit.Test;
>>  -
>>  -import java.util.Map;
>>  -import java.util.Optional;
>>  -
>>  -public class EnvironmentPropertySourceTest {
>>  -
>>  -    private EnvironmentPropertySource propertySource = new 
>>  EnvironmentPropertySource();
>>  -
>>  -
>>  -    @Test
>>  -    public void testGetOrdinal() {
>>  -        Assert.assertEquals(DefaultOrdinal.ENVIRONMENT_PROPERTIES, 
>>  propertySource.getOrdinal());
>>  -    }
>>  -
>>  -    @Test
>>  -    public void testGet() {
>>  -        String environmentPropertyToCheck = 
>>  System.getenv().keySet().iterator().next();
>>  -
>>  -        Optional<String> value = 
>>  propertySource.get(environmentPropertyToCheck);
>>  -        Assert.assertTrue(value.isPresent());
>>  -        Assert.assertEquals(System.getenv(environmentPropertyToCheck), 
>>  value.get());
>>  -    }
>>  -
>>  -    @Test
>>  -    public void testGetProperties() {
>>  -        Map<String, String> environmentProperties = System.getenv();
>>  -
>>  -        Assert.assertEquals(environmentProperties.size(), 
>>  propertySource.getProperties().size());
>>  -
>>  -        for (Map.Entry<String, String> propertySourceEntry : 
>>  propertySource.getProperties().entrySet()) {
>>  -            Assert.assertEquals("Entry values for key '" + 
>>  propertySourceEntry.getKey() + "' do not match",
>>  -                                
>>  environmentProperties.get(propertySourceEntry.getKey()), 
>>  propertySourceEntry.getValue());
>>  -        }
>>  -
>>  -        // modification is not allowed
>>  -        try {
>>  -            propertySource.getProperties().put("add.new.keys", 
>>  "must throw exception");
>>  -            Assert.fail(UnsupportedOperationException.class.getName() + 
> " 
>>  expected");
>>  -        }
>>  -        catch (UnsupportedOperationException e) {
>>  -            // expected -> all is fine
>>  -        }
>>  -    }
>>  -
>>  -
>>  -}
>> 
>> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
>>  ----------------------------------------------------------------------
>>  diff --git 
>> 
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java 
> 
>> 
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
>>  new file mode 100644
>>  index 0000000..5fa90b1
>>  --- /dev/null
>>  +++ 
>> 
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
>>  @@ -0,0 +1,32 @@
>>  +/*
>>  + * Licensed to the Apache Software Foundation (ASF) under one
>>  + * or more contributor license agreements.  See the NOTICE file
>>  + * distributed with this work for additional information
>>  + * regarding copyright ownership.  The ASF licenses this file
>>  + * to you under the Apache License, Version 2.0 (the
>>  + * "License"); you may not use this file except in compliance
>>  + * with the License.  You may obtain a copy of the License at
>>  + *
>>  + *  http://www.apache.org/licenses/LICENSE-2.0
>>  + *
>>  + * Unless required by applicable law or agreed to in writing,
>>  + * software distributed under the License is distributed on an
>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>  + * KIND, either express or implied.  See the License for the
>>  + * specific language governing permissions and limitations
>>  + * under the License.
>>  + */
>>  +package org.apache.tamaya.core.testdata;
>>  +
>>  +import org.apache.tamaya.core.PathBasedPropertySourceProvider;
>>  +import org.apache.tamaya.core.formats.PropertiesFormat;
>>  +
>>  +/**
>>  + * Test provider reading properties from 
> classpath:cfg/defaults/**.properties.
>>  + */
>>  +public class TestPropertyDefaultSourceProvider extends 
>>  PathBasedPropertySourceProvider{
>>  +
>>  +    public TestPropertyDefaultSourceProvider() {
>>  +        super("default-testdata-properties", new 
>>  PropertiesFormat(100), "classpath:cfg/defaults/**/*.properties");
>>  +    }
>>  +}
>> 
>> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
>>  ----------------------------------------------------------------------
>>  diff --git 
>> 
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java 
>> 
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
>>  deleted file mode 100644
>>  index d1314aa..0000000
>>  --- 
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
>>  +++ /dev/null
>>  @@ -1,55 +0,0 @@
>>  -/*
>>  - * Licensed to the Apache Software Foundation (ASF) under one
>>  - * or more contributor license agreements.  See the NOTICE file
>>  - * distributed with this work for additional information
>>  - * regarding copyright ownership.  The ASF licenses this file
>>  - * to you under the Apache License, Version 2.0 (the
>>  - * "License"); you may not use this file except in compliance
>>  - * with the License.  You may obtain a copy of the License at
>>  - *
>>  - *  http://www.apache.org/licenses/LICENSE-2.0
>>  - *
>>  - * Unless required by applicable law or agreed to in writing,
>>  - * software distributed under the License is distributed on an
>>  - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>  - * KIND, either express or implied.  See the License for the
>>  - * specific language governing permissions and limitations
>>  - * under the License.
>>  - */
>>  -package org.apache.tamaya.core.testdata;
>>  -
>>  -import java.util.HashMap;
>>  -import java.util.Map;
>>  -
>>  -import org.apache.tamaya.core.propertysource.BasePropertySource;
>>  -
>>  -/**
>>  - * Test provider reading properties from 
> classpath:cfg/final/**.properties.
>>  - */
>>  -public class TestPropertySource extends BasePropertySource {
>>  -
>>  -    private static final Map<String, String> VALUES;
>>  -    static {
>>  -        VALUES = new HashMap<String, String>();
>>  -        VALUES.put("name", "Robin");
>>  -        VALUES.put("name2", "Sabine");
>>  -        VALUES.put("name3", "Lukas");
>>  -        VALUES.put("name4", "Sereina");
>>  -        VALUES.put("name5", "Benjamin");
>>  -    }
>>  -
>>  -
>>  -    public TestPropertySource() {
>>  -        initialzeOrdinal(100);
>>  -    }
>>  -
>>  -    @Override
>>  -    public String getName() {
>>  -        return "TestPropertySource";
>>  -    }
>>  -
>>  -    @Override
>>  -    public Map<String, String> getProperties() {
>>  -        return VALUES;
>>  -    }
>>  -}
>> 
>> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
>>  ----------------------------------------------------------------------
>>  diff --git 
>> 
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java 
> 
>> 
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
>>  new file mode 100644
>>  index 0000000..beafbf9
>>  --- /dev/null
>>  +++ 
>> 
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
>>  @@ -0,0 +1,32 @@
>>  +/*
>>  + * Licensed to the Apache Software Foundation (ASF) under one
>>  + * or more contributor license agreements.  See the NOTICE file
>>  + * distributed with this work for additional information
>>  + * regarding copyright ownership.  The ASF licenses this file
>>  + * to you under the Apache License, Version 2.0 (the
>>  + * "License"); you may not use this file except in compliance
>>  + * with the License.  You may obtain a copy of the License at
>>  + *
>>  + *  http://www.apache.org/licenses/LICENSE-2.0
>>  + *
>>  + * Unless required by applicable law or agreed to in writing,
>>  + * software distributed under the License is distributed on an
>>  + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>  + * KIND, either express or implied.  See the License for the
>>  + * specific language governing permissions and limitations
>>  + * under the License.
>>  + */
>>  +package org.apache.tamaya.core.testdata;
>>  +
>>  +import org.apache.tamaya.core.PathBasedPropertySourceProvider;
>>  +import org.apache.tamaya.core.formats.PropertiesFormat;
>>  +
>>  +/**
>>  + * Test provider reading properties from 
> classpath:cfg/final/**.properties.
>>  + */
>>  +public class TestPropertySourceProvider extends 
>>  PathBasedPropertySourceProvider{
>>  +
>>  +    public TestPropertySourceProvider() {
>>  +        super("final-testdata-properties", new 
> PropertiesFormat(200), 
>>  "classpath:cfg/final/**/*.properties");
>>  +    }
>>  +}
>> 
>> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
>>  ----------------------------------------------------------------------
>>  diff --git 
>> 
> a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource 
> 
>> 
> b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
>>  deleted file mode 100644
>>  index e6f7fad..0000000
>>  --- 
>> 
> a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
>>  +++ /dev/null
>>  @@ -1,19 +0,0 @@
>>  -#
>>  -# Licensed to the Apache Software Foundation (ASF) under one
>>  -# or more contributor license agreements.  See the NOTICE file
>>  -# distributed with this work for additional information
>>  -# regarding copyright ownership.  The ASF licenses this file
>>  -# to you under the Apache License, Version 2.0 (the
>>  -# "License"); you may not use this file except in compliance
>>  -# with the License.  You may obtain a copy current the License at
>>  -#
>>  -#    http://www.apache.org/licenses/LICENSE-2.0
>>  -#
>>  -# Unless required by applicable law or agreed to in writing,
>>  -# software distributed under the License is distributed on an
>>  -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>  -# KIND, either express or implied.  See the License for the
>>  -# specific language governing permissions and limitations
>>  -# under the License.
>>  -#
>>  -org.apache.tamaya.core.testdata.TestPropertySource
>>  \ No newline at end of file
>> 
>> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
>>  ----------------------------------------------------------------------
>>  diff --git 
>> 
> a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider 
> 
>> 
> b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
>>  new file mode 100644
>>  index 0000000..9db0ef4
>>  --- /dev/null
>>  +++ 
>> 
> b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
>>  @@ -0,0 +1,20 @@
>>  +#
>>  +# Licensed to the Apache Software Foundation (ASF) under one
>>  +# or more contributor license agreements.  See the NOTICE file
>>  +# distributed with this work for additional information
>>  +# regarding copyright ownership.  The ASF licenses this file
>>  +# to you under the Apache License, Version 2.0 (the
>>  +# "License"); you may not use this file except in compliance
>>  +# with the License.  You may obtain a copy current the License at
>>  +#
>>  +#    http://www.apache.org/licenses/LICENSE-2.0
>>  +#
>>  +# Unless required by applicable law or agreed to in writing,
>>  +# software distributed under the License is distributed on an
>>  +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>  +# KIND, either express or implied.  See the License for the
>>  +# specific language governing permissions and limitations
>>  +# under the License.
>>  +#
>>  +org.apache.tamaya.core.testdata.TestPropertyDefaultSourceProvider
>>  +org.apache.tamaya.core.testdata.TestPropertySourceProvider
>>  \ No newline at end of file
>> 
> 

Re: [2/4] incubator-tamaya git commit: TAMAYA-42, 43, 44: Readded non Spring related parts. Simplified resource API. Readded other tests.

Posted by Anatole Tresch <at...@gmail.com>.
Hi Mark

see inline...

2015-01-04 9:10 GMT+01:00 Mark Struberg <st...@yahoo.de>:

> Anatole, WHY do we need all of this?
>
> It is NOWHERE used!

Why do we add 21 classes which don't provide anything useful to the project?
>

​Tbd discussed what is useful and what not. But just claiming it is useless
is inpolite, not worth answering. and does not qualify as a mentor that
should help to motivate people having an open discussion. Seems that you
still not get that social aspect here! I can say to you I do expect a
single person of my colluegues to want to contribute anything to this
project with that kind of mindset...

There was even a VOTE that we should keep it simple and just do the things
> we need.
>
I agree with the vote. But it is nevertheless tbd, what is minimal. It is
YOUR personal view (perhaps also the ones of others), that we do provide a
core part that is so ridiculously minimal that it is no use for many users,
especially in the enterprise context, because everything slightly
*normal *(such
as accessing a configuration location instead of defining explicitly all
yourself​) is seen as overkill even for the core implementation part. The
same is true for separating the format of a configuration from the way,
where it is stored.

>
> I really don't get it. Is our goal to create a lightweight but flexible
> configuration system or is our goal to become big and fat?
>
​For me with what is now in core it would be all I see. An abstraction for
resources is very helpful and applies to all subsequent extensions, be it
additional formats, additional ways of gathering configs from other
locations than classpath urls and files. It also allows us to optimize
certain things, such as caching of resources and implementing updateable
resources. All features e.g. an URI does not provide in SE.​


> Maybe it makes sense but if so then please explain it to us.
>
>
> 1.) Why do we read in a specific format?
>
​There will be specific formats. I just think the ones already implemented
with Properties are worth being provided out of hte box. If someone wants
to read some properties files he can do it easily and dont need any other
dependency. That is what I consider minimal.​



> All the system is handling String/String and only in the last step it
> *probably* gets converted into a target Type. I fail to see the benefit.
> Please explain it to us.
>
​The type safe config access is a key feature requested by all users and
experts I have talked to. I personally agree with that, and I think your
view here is much to constraint on mathematical purity than user
friendliness.​


>
> 2.) Why do we need all the Resource implementations?
>
​Basically we can discuss, if we want to add all of them. But it is not
much code and they are useful for all subsequent modules that want to use
resources. Since resources are very useful in combination with
configuration formats, I would not externalize them, since this would
require to add additional dependencies to all subsequent users and make
things complicated, vecause core is too minimalistic IMO.
​

Java provides Resource handling out of the box. Again: we don't need any
> scripting. So why add some handling for dynamic scenarios which we do not
> have? This is basically a copy of Spring.io. But we simply don't have
> anything scripted in XML as Spring does. So why should we add it?
>
​Sorry, Mark. I dont get that point. I dont see any scripting in the given
code. It is just a resource abstraction that allows be to define my
configuration resources more descriptively. ​I explained the use case a
felt thousand times already. Would be time that you finally get it. And
said that the Java resource handling is not enough and it there is no
uniform abstraction over it (not interface). You can use URIs, but you will
have to add much code outside of it, you can take URLs but you have to
register protocol handlers for other things, you can use files, but, well,
it is only for files. Thats the reason for abstracting resources, it is NOT
about scripting.

I'm really tired of seeing code all over the place which is not helpful for
> the project. Please don't add things we don't really need.
>
>
​Personally I think you are a nice guy. But it is a fact that I am really
upset of your way of mentoring that project. Your views are even more
constraint than it would be with a JSR. I am sure it is not motivating
other people here to join the discussions or even contribute code and it
would make a JSR fail for sure. Many of my colluegues already stopped
contributing here.

No open discussions, claims without technical deepness (which you have, but
you have to take the time to put that in a mail for an open discussion), no
appreciation for work done, it is simply not constructive os in short it is
no fun !

​If I would write the project report for January, I would like to add the
current mentoring setup as a project risk that must be solved.

Cheers,
Anatole​



> > On Sunday, 4 January 2015, 2:52, "anatole@apache.org" <
> anatole@apache.org> wrote:
> > >T AMAYA-42,43,44: Readded non Spring related parts. Simplified resource
> API.
> > Readded other tests.
> >
> >
> > Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo
> > Commit:
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/cc237eb4
> > Tree:
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/cc237eb4
> > Diff:
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/cc237eb4
> >
> > Branch: refs/heads/master
> > Commit: cc237eb41b7d0c660261f451f47bbf07b7770c46
> > Parents: 59a9e21
> > Author: anatole <an...@apache.org>
> > Authored: Sun Jan 4 02:17:56 2015 +0100
> > Committer: anatole <an...@apache.org>
> > Committed: Sun Jan 4 02:26:23 2015 +0100
> >
> > ----------------------------------------------------------------------
> > .../org/apache/tamaya/spi/PropertyFilter.java   |  10 +-
> > .../core/PathBasedPropertySourceProvider.java   |  93 ++++++++++
> > .../core/ResourcePropertySourceProvider.java    | 102 +++++++++++
> > .../core/formats/ConfigurationFormat.java       |  53 ++++++
> > .../tamaya/core/formats/PropertiesFormat.java   | 114 ++++++++++++
> > .../core/formats/PropertiesXmlFormat.java       | 115 ++++++++++++
> > .../core/internal/DefaultConfiguration.java     |  27 ++-
> > .../internal/resource/ClassPathResource.java    | 178 +++++++++++++++++++
> > .../resource/DefaultResourceLoader.java         |  93 ++++++++++
> > .../core/internal/resource/FileResource.java    | 162 +++++++++++++++++
> > .../internal/resource/InputStreamResource.java  | 117 ++++++++++++
> > .../core/resources/InputStreamSupplier.java     |  37 ++++
> > .../apache/tamaya/core/resources/Resource.java  | 115 ++++++++++++
> > .../tamaya/core/resources/ResourceLoader.java   |  91 ++++++++++
> > .../apache/tamaya/core/ConfigurationTest.java   |   6 +
> > .../EnvironmentPropertySourceTest.java          |  70 --------
> > .../TestPropertyDefaultSourceProvider.java      |  32 ++++
> > .../core/testdata/TestPropertySource.java       |  55 ------
> > .../testdata/TestPropertySourceProvider.java    |  32 ++++
> > .../org.apache.tamaya.spi.PropertySource        |  19 --
> > ...org.apache.tamaya.spi.PropertySourceProvider |  20 +++
> > 21 files changed, 1388 insertions(+), 153 deletions(-)
> > ----------------------------------------------------------------------
> >
> >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> > ----------------------------------------------------------------------
> > diff --git a/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> > b/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> > index 7479008..c8626fc 100644
> > --- a/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> > +++ b/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> > @@ -19,7 +19,7 @@
> > package org.apache.tamaya.spi;
> >
> >
> > -import java.util.Map;
> > +import java.util.function.Function;
> >
> > /**
> >   * <p>Interface for filtering the current map of properties during the
> > evaluation of the chain of PropertySources.
> > @@ -27,7 +27,7 @@ import java.util.Map;
> >   * hereby is defined by the corresponding {@code @Priority}
> > annotation.</p>
> >   * <p>Filters </p>
> >   */
> > -public interface PropertyFilter<T>{
> > +public interface PropertyFilter{
> >
> >      /**
> >       * <p>Maps the current {@code valueToBeFiltered} value to a new
> > value. The resulting value will be used as the result
> > @@ -44,10 +44,10 @@ public interface PropertyFilter<T>{
> >       *
> >       * @param key the key accessed, not null.
> >       * @param valueToBeFiltered the value to be filtered, not null.
> > -     * @param currentMap the current input property map, not null. Can
> be used
> > for resolution of the filtered value
> > -     *                   or as datasource for additional
> meta-information, such
> > as categories, sensitivity etc.
> > +     * @param propertyValueProvider accessor for reading additional (eg
> > metadata) properties to perform correct
> > +     *                              filtering, never null.
> >       * @return the filtered map, never null.
> >       */
> > -    String filterProperty(String key, String valueToBeFiltered,
> > Map<String,String> currentMap);
> > +    String filterProperty(String key, String valueToBeFiltered,
> > Function<String,String> propertyValueProvider);
> >
> > }
> >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
> > ----------------------------------------------------------------------
> > diff --git
> >
> a/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
> >
> b/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
> > new file mode 100644
> > index 0000000..31dbf4b
> > --- /dev/null
> > +++
> >
> b/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
> > @@ -0,0 +1,93 @@
> > +/*
> > + * Licensed to the Apache Software Foundation (ASF) under one
> > + * or more contributor license agreements.  See the NOTICE file
> > + * distributed with this work for additional information
> > + * regarding copyright ownership.  The ASF licenses this file
> > + * to you under the Apache License, Version 2.0 (the
> > + * "License"); you may not use this file except in compliance
> > + * with the License.  You may obtain a copy of the License at
> > + *
> > + *  http://www.apache.org/licenses/LICENSE-2.0
> > + *
> > + * Unless required by applicable law or agreed to in writing,
> > + * software distributed under the License is distributed on an
> > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > + * KIND, either express or implied.  See the License for the
> > + * specific language governing permissions and limitations
> > + * under the License.
> > + */
> > +package org.apache.tamaya.core;
> > +
> > +import org.apache.tamaya.core.formats.ConfigurationFormat;
> > +import org.apache.tamaya.core.resources.Resource;
> > +import org.apache.tamaya.core.resources.ResourceLoader;
> > +import org.apache.tamaya.spi.PropertySource;
> > +import org.apache.tamaya.spi.PropertySourceProvider;
> > +import org.apache.tamaya.spi.ServiceContext;
> > +
> > +import java.util.ArrayList;
> > +import java.util.Arrays;
> > +import java.util.Collection;
> > +import java.util.List;
> > +import java.util.Objects;
> > +import java.util.logging.Level;
> > +import java.util.logging.Logger;
> > +
> > +/**
> > + * Implementation of a {@link PropertySourceProvider} that reads
> > configuration from some given resource paths
> > + * and using the given formats. The resource path are resolved using the
> > current
> > + * {@link org.apache.tamaya.core.resources.ResourceLoader} active.
> > + */
> > +public class PathBasedPropertySourceProvider implements
> PropertySourceProvider
> > {
> > +    /** The logger used. */
> > +    private static final Logger LOG =
> > Logger.getLogger(PathBasedPropertySourceProvider.class.getName());
> > +    /** The property source base name, will be used for creating a
> useful name
> > of the
> > +     * {@link org.apache.tamaya.spi.PropertySource} created. */
> > +    private String sourceName;
> > +    /** The config formats supported for the given location/resource
> paths. */
> > +    private List<ConfigurationFormat> configFormats = new
> > ArrayList<>();
> > +    /** The paths to be evaluated. */
> > +    private List<String> paths = new ArrayList<>();
> > +
> > +    /**
> > +     * Creates a new instance.
> > +     * @param sourceName the base name of the configuration, used for
> creating
> > PropertySource child names.
> > +     * @param formats the formats to be used, not null, not empty.
> > +     * @param paths the paths to be resolved, not null, not empty.
> > +     */
> > +    public PathBasedPropertySourceProvider(String sourceName,
> > List<ConfigurationFormat> formats, String... paths) {
> > +        this.sourceName = Objects.requireNonNull(sourceName);
> > +        this.configFormats.addAll(Objects.requireNonNull(formats));
> > +        this.paths.addAll(Arrays.asList(Objects.requireNonNull(paths)));
> > +    }
> > +
> > +    /**
> > +     * Creates a new instance.
> > +     * @param sourceName the base name of the configuration, used for
> creating
> > PropertySource child names.
> > +     * @param format the format to be used.
> > +     * @param paths the paths to be resolved, not null, not empty.
> > +     */
> > +    public PathBasedPropertySourceProvider(String sourceName,
> > ConfigurationFormat format, String... paths) {
> > +        this.sourceName = Objects.requireNonNull(sourceName);
> > +        this.configFormats.add(Objects.requireNonNull(format));
> > +        this.paths.addAll(Arrays.asList(Objects.requireNonNull(paths)));
> > +    }
> > +
> > +    @Override
> > +    public Collection<PropertySource> getPropertySources() {
> > +        List<PropertySource> propertySources = new ArrayList<>();
> > +        paths.forEach((path) -> {
> > +            for (Resource res :
> >
> ServiceContext.getInstance().getService(ResourceLoader.class).get().getResources(path))
> > {
> > +                try {
> > +                    for (ConfigurationFormat format : configFormats) {
> > +
> > propertySources.addAll(format.readConfiguration(sourceName, res));
> > +                    }
> > +                } catch (Exception e) {
> > +                    LOG.log(Level.WARNING, "Failed to add resource based
> > config: " + res.getName(), e);
> > +                }
> > +            }
> > +        });
> > +        return propertySources;
> > +    }
> > +
> > +}
> >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
> > ----------------------------------------------------------------------
> > diff --git
> >
> a/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
> >
> b/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
> > new file mode 100644
> > index 0000000..de6b578
> > --- /dev/null
> > +++
> >
> b/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
> > @@ -0,0 +1,102 @@
> > +/*
> > + * Licensed to the Apache Software Foundation (ASF) under one
> > + * or more contributor license agreements.  See the NOTICE file
> > + * distributed with this work for additional information
> > + * regarding copyright ownership.  The ASF licenses this file
> > + * to you under the Apache License, Version 2.0 (the
> > + * "License"); you may not use this file except in compliance
> > + * with the License.  You may obtain a copy of the License at
> > + *
> > + *  http://www.apache.org/licenses/LICENSE-2.0
> > + *
> > + * Unless required by applicable law or agreed to in writing,
> > + * software distributed under the License is distributed on an
> > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > + * KIND, either express or implied.  See the License for the
> > + * specific language governing permissions and limitations
> > + * under the License.
> > + */
> > +package org.apache.tamaya.core;
> > +
> > +import org.apache.tamaya.core.formats.ConfigurationFormat;
> > +import org.apache.tamaya.core.resources.Resource;
> > +import org.apache.tamaya.spi.PropertySource;
> > +import org.apache.tamaya.spi.PropertySourceProvider;
> > +
> > +import java.util.ArrayList;
> > +import java.util.Arrays;
> > +import java.util.Collection;
> > +import java.util.List;
> > +import java.util.Objects;
> > +import java.util.logging.Logger;
> > +
> > +/**
> > + * Implementation of a {@link
> > org.apache.tamaya.spi.PropertySourceProvider} that is based on a single
> resource
> > + * and a number of formats.
> > + */
> > +public class ResourcePropertySourceProvider implements
> PropertySourceProvider
> > {
> > +    /** The logger used. */
> > +    private static final Logger LOG =
> > Logger.getLogger(ResourcePropertySourceProvider.class.getName());
> > +    /** The supported formats. */
> > +    private List<ConfigurationFormat> formats = new ArrayList<>();
> > +    /** The resource. */
> > +    private Resource resource;
> > +    /** The source name used for creating the PropertySource names. */
> > +    private String sourceName;
> > +
> > +    /**
> > +     * Creates a new instance.
> > +     * @param resource the {@link
> > org.apache.tamaya.core.resources.Resource}, not null.
> > +     * @param formats the supported formats, not empty.
> > +     */
> > +    public ResourcePropertySourceProvider(String sourceName, Resource
> resource,
> > ConfigurationFormat... formats) {
> > +        this(sourceName, resource, Arrays.asList(formats));
> > +    }
> > +
> > +    /**
> > +     * Creates a new instance.
> > +     * @param resource the {@link
> > org.apache.tamaya.core.resources.Resource}, not null.
> > +     * @param formats the supported formats, not empty.
> > +     */
> > +    public ResourcePropertySourceProvider(String sourceName, Resource
> resource,
> > List<ConfigurationFormat> formats) {
> > +        this.resource = Objects.requireNonNull(resource);
> > +        this.sourceName = Objects.requireNonNull(sourceName);
> > +        if(formats.size()==0){
> > +            throw new IllegalArgumentException("Format required.");
> > +        }
> > +        this.formats.addAll(formats);
> > +    }
> > +
> > +
> > +    /**
> > +     * Get the underlying resource.
> > +     *
> > +     * @return the underlying resource, never null.
> > +     */
> > +    public Resource getResource() {
> > +        return this.resource;
> > +    }
> > +
> > +
> > +    @Override
> > +    public String toString() {
> > +        return "ResourcePropertySourceProvider{" +
> > +                "resource=" + resource +
> > +                ", formats=+" + formats +
> > +                '}';
> > +    }
> > +
> > +    @Override
> > +    public Collection<PropertySource> getPropertySources() {
> > +        List<PropertySource> propertySources = new ArrayList<>();
> > +        for (ConfigurationFormat format : formats) {
> > +            try {
> > +
> propertySources.addAll(format.readConfiguration(sourceName,
> > resource));
> > +            } catch (Exception e) {
> > +                LOG.info(() -> "Format was not matching: " +
> > format + " for resource: " + resource.getName());
> > +            }
> > +        }
> > +        return propertySources;
> > +    }
> > +
> > +}
> >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
> > ----------------------------------------------------------------------
> > diff --git
> >
> a/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
> >
> b/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
> > new file mode 100644
> > index 0000000..5d289bb
> > --- /dev/null
> > +++
> b/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
> > @@ -0,0 +1,53 @@
> > +/*
> > + * Licensed to the Apache Software Foundation (ASF) under one
> > + * or more contributor license agreements.  See the NOTICE file
> > + * distributed with this work for additional information
> > + * regarding copyright ownership.  The ASF licenses this file
> > + * to you under the Apache License, Version 2.0 (the
> > + * "License"); you may not use this file except in compliance
> > + * with the License.  You may obtain a copy of the License at
> > + *
> > + *  http://www.apache.org/licenses/LICENSE-2.0
> > + *
> > + * Unless required by applicable law or agreed to in writing,
> > + * software distributed under the License is distributed on an
> > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > + * KIND, either express or implied.  See the License for the
> > + * specific language governing permissions and limitations
> > + * under the License.
> > + */
> > +package org.apache.tamaya.core.formats;
> > +
> > +import org.apache.tamaya.core.resources.Resource;
> > +import org.apache.tamaya.spi.PropertySource;
> > +
> > +import java.io.IOException;
> > +import java.util.Collection;
> > +
> > +/**
> > + * Implementations current this class encapsulate the mechanism how to
> read a
> > + * resource including interpreting the format correctly (e.g. xml vs.
> > + * properties). In most cases file only contains entries of the same
> priority,
> > which would then
> > + * result in only one {@link PropertySource}. Complex file formats,
> > hoiwever, may contain entries
> > + * of different priorities. In this cases, each ordinal type found must
> be
> > returned as a separate
> > + * {@link PropertySource} instance.
> > + */
> > +@FunctionalInterface
> > +public interface ConfigurationFormat {
> > +
> > +    /**
> > +     * Reads a list {@link org.apache.tamaya.spi.PropertySource}
> instances
> > from a resource, using this format.
> > +     * If the configuration format only contains entries of one ordinal
> type,
> > normally only one single
> > +     * instance of PropertySource is returned. Nevertheless custom
> formats may
> > contain different sections or parts,
> > +     * where each part maps to a different target rdinal (eg defaults,
> domain
> > config and app config). In the
> > +     * ladder case multiple PropertySources can be returned, each one
> with its
> > own ordinal and the corresponding
> > +     * entries.
> > +     *
> > +     * @param sourceName name to be used for constructing a useful name
> for the
> > created
> > +     *                   {@link org.apache.tamaya.spi.PropertySource}
> > instances.
> > +     * @param resource   the configuration resource, not null
> > +     * @return the corresponding {@link
> > org.apache.tamaya.spi.PropertySource} instances, never {@code null}.
> > +     */
> > +    Collection<PropertySource> readConfiguration(String sourceName,
> > Resource resource) throws IOException;
> > +
> > +}
> >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
> > ----------------------------------------------------------------------
> > diff --git
> > a/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
> > b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
> > new file mode 100644
> > index 0000000..3584f8e
> > --- /dev/null
> > +++
> b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
> > @@ -0,0 +1,114 @@
> > +/*
> > + * Licensed to the Apache Software Foundation (ASF) under one
> > + * or more contributor license agreements.  See the NOTICE file
> > + * distributed with this work for additional information
> > + * regarding copyright ownership.  The ASF licenses this file
> > + * to you under the Apache License, Version 2.0 (the
> > + * "License"); you may not use this file except in compliance
> > + * with the License.  You may obtain a copy of the License at
> > + *
> > + *  http://www.apache.org/licenses/LICENSE-2.0
> > + *
> > + * Unless required by applicable law or agreed to in writing,
> > + * software distributed under the License is distributed on an
> > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > + * KIND, either express or implied.  See the License for the
> > + * specific language governing permissions and limitations
> > + * under the License.
> > + */
> > +package org.apache.tamaya.core.formats;
> > +
> > +import org.apache.tamaya.core.resources.Resource;
> > +import org.apache.tamaya.spi.PropertySource;
> > +
> > +import java.io.InputStream;
> > +import java.util.ArrayList;
> > +import java.util.Collection;
> > +import java.util.Collections;
> > +import java.util.List;
> > +import java.util.Map;
> > +import java.util.Optional;
> > +import java.util.Properties;
> > +import java.util.logging.Level;
> > +import java.util.logging.Logger;
> > +
> > +/**
> > + * Implementation of a {@link
> > org.apache.tamaya.core.formats.ConfigurationFormat} for -properties
> files.
> > + *
> > + * @see java.util.Properties#load(java.io.InputStream)
> > + */
> > +public class PropertiesFormat implements ConfigurationFormat {
> > +    /**
> > +     * The logger.
> > +     */
> > +    private final static Logger LOG =
> > Logger.getLogger(PropertiesFormat.class.getName());
> > +
> > +    /**
> > +     * The target ordinal.
> > +     */
> > +    private int ordinal;
> > +
> > +    /**
> > +     * Creates a new format instance, hereby producing entries with the
> given
> > ordinal, if not overridden by the
> > +     * configuration itself.
> > +     * TODO document and implement override feature
> > +     * @param ordinal the target ordinal.
> > +     */
> > +    public PropertiesFormat(int ordinal) {
> > +        this.ordinal = ordinal;
> > +    }
> > +
> > +    /**
> > +     * Get the target ordinal, produced by this format.
> > +     *
> > +     * @return the target ordinal
> > +     */
> > +    public int getOrdinal() {
> > +        return ordinal;
> > +    }
> > +
> > +    @SuppressWarnings("unchecked")
> > +    @Override
> > +    public Collection<PropertySource> readConfiguration(String baseName,
> > Resource resource) {
> > +        final String sourceName =
> > (baseName==null?"Properties:":baseName) + resource.getName();
> > +        if (resource.exists()) {
> > +            List<PropertySource> propertySources = new
> > ArrayList<>();
> > +            try (InputStream is = resource.getInputStream()) {
> > +                final Properties p = new Properties();
> > +                p.load(is);
> > +                propertySources.add(new PropertySource() {
> > +                    @Override
> > +                    public int getOrdinal() {
> > +                        return ordinal;
> > +                    }
> > +
> > +                    @Override
> > +                    public String getName() {
> > +                        return sourceName;
> > +                    }
> > +
> > +                    @Override
> > +                    public Optional<String> get(String key) {
> > +                        return Optional.ofNullable(p.getProperty(key));
> > +                    }
> > +
> > +                    @Override
> > +                    public Map<String, String> getProperties() {
> > +                        return Map.class.cast(p);
> > +                    }
> > +                });
> > +                return propertySources;
> > +            } catch (Exception e) {
> > +                LOG.log(Level.FINEST, e, () -> "Failed to read config
> > from resource: " + resource);
> > +            }
> > +        }
> > +        return Collections.emptyList();
> > +    }
> > +
> > +    @Override
> > +    public String toString() {
> > +        return "PropertiesFormat{" +
> > +                "ordinal=" + ordinal +
> > +                '}';
> > +    }
> > +}
> >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
> > ----------------------------------------------------------------------
> > diff --git
> >
> a/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
> >
> b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
> > new file mode 100644
> > index 0000000..3f77810
> > --- /dev/null
> > +++
> b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
> > @@ -0,0 +1,115 @@
> > +/*
> > + * Licensed to the Apache Software Foundation (ASF) under one
> > + * or more contributor license agreements.  See the NOTICE file
> > + * distributed with this work for additional information
> > + * regarding copyright ownership.  The ASF licenses this file
> > + * to you under the Apache License, Version 2.0 (the
> > + * "License"); you may not use this file except in compliance
> > + * with the License.  You may obtain a copy of the License at
> > + *
> > + *  http://www.apache.org/licenses/LICENSE-2.0
> > + *
> > + * Unless required by applicable law or agreed to in writing,
> > + * software distributed under the License is distributed on an
> > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > + * KIND, either express or implied.  See the License for the
> > + * specific language governing permissions and limitations
> > + * under the License.
> > + */
> > +package org.apache.tamaya.core.formats;
> > +
> > +import org.apache.tamaya.core.resources.Resource;
> > +import org.apache.tamaya.spi.PropertySource;
> > +
> > +import java.io.InputStream;
> > +import java.util.ArrayList;
> > +import java.util.Collection;
> > +import java.util.Collections;
> > +import java.util.List;
> > +import java.util.Map;
> > +import java.util.Optional;
> > +import java.util.Properties;
> > +import java.util.logging.Level;
> > +import java.util.logging.Logger;
> > +
> > +/**
> > + * Implementation of a {@link
> > org.apache.tamaya.core.formats.ConfigurationFormat} for xml property
> > + * files.
> > + *
> > + * @see java.util.Properties#loadFromXML(java.io.InputStream)
> > + */
> > +public class PropertiesXmlFormat implements ConfigurationFormat {
> > +    /**
> > +     * The logger.
> > +     */
> > +    private final static Logger LOG =
> > Logger.getLogger(PropertiesXmlFormat.class.getName());
> > +
> > +    /**
> > +     * The target ordinal.
> > +     */
> > +    private int ordinal;
> > +
> > +    /**
> > +     * Creates a new format instance, producing entries for the given
> ordinal,
> > if not overridden by a
> > +     * config entry itself.
> > +     * TODO document and implement override feature
> > +     * @param ordinal the target ordinal.
> > +     */
> > +    public PropertiesXmlFormat(int ordinal) {
> > +        this.ordinal = ordinal;
> > +    }
> > +
> > +    /**
> > +     * Get the target ordinal, produced by this format.
> > +     *
> > +     * @return the target ordinal
> > +     */
> > +    public int getOrdinal() {
> > +        return ordinal;
> > +    }
> > +
> > +    @SuppressWarnings("unchecked")
> > +    @Override
> > +    public Collection<PropertySource> readConfiguration(String baseName,
> > Resource resource) {
> > +        if (resource.exists()) {
> > +            final String sourceName =
> > (baseName==null?"Properties:":baseName) + resource.getName();
> > +            List<PropertySource> propertySources = new
> > ArrayList<>();
> > +            try (InputStream is = resource.getInputStream()) {
> > +                final Properties p = new Properties();
> > +                p.loadFromXML(is);
> > +                propertySources.add(new PropertySource() {
> > +                    @Override
> > +                    public int getOrdinal() {
> > +                        return ordinal;
> > +                    }
> > +
> > +                    @Override
> > +                    public String getName() {
> > +                        return sourceName;
> > +                    }
> > +
> > +                    @Override
> > +                    public Optional<String> get(String key) {
> > +                        return Optional.ofNullable(p.getProperty(key));
> > +                    }
> > +
> > +                    @Override
> > +                    public Map<String, String> getProperties() {
> > +                        return Map.class.cast(p);
> > +                    }
> > +                });
> > +                return propertySources;
> > +            } catch (Exception e) {
> > +                LOG.log(Level.FINEST, e, () -> "Failed to read config
> > from resource: " + resource);
> > +            }
> > +        }
> > +        return Collections.emptyList();
> > +    }
> > +
> > +    @Override
> > +    public String toString() {
> > +        return "PropertiesXmlFormat{" +
> > +                "ordinal=" + ordinal +
> > +                '}';
> > +    }
> > +}
> >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> > ----------------------------------------------------------------------
> > diff --git
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> > index 0a39b7d..3769e27 100644
> > ---
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> > +++
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> > @@ -22,6 +22,7 @@ import org.apache.tamaya.ConfigException;
> > import org.apache.tamaya.Configuration;
> > import org.apache.tamaya.spi.ConfigurationContext;
> > import org.apache.tamaya.spi.PropertyConverter;
> > +import org.apache.tamaya.spi.PropertyFilter;
> > import org.apache.tamaya.spi.PropertySource;
> > import org.apache.tamaya.spi.ServiceContext;
> >
> > @@ -33,6 +34,7 @@ import java.util.Map;
> > import java.util.Optional;
> > import java.util.logging.Level;
> > import java.util.logging.Logger;
> > +import java.util.stream.Collectors;
> >
> > /**
> >   * Implementation of the Configuration API. This class uses the current
> > {@link ConfigurationContext} to evaluate the
> > @@ -56,13 +58,21 @@ public class DefaultConfiguration implements
> Configuration
> > {
> >      @Override
> >      public Optional<String> get(String key) {
> >          List<PropertySource> propertySources =
> >
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertySources();
> > +        String unfilteredValue = null;
> >          for (PropertySource propertySource : propertySources) {
> >              Optional<String> value = propertySource.get(key);
> >              if (value.isPresent()) {
> > -                return value;
> > +                unfilteredValue = value.get();
> > +                break;
> >              }
> >          }
> > -        return Optional.empty();
> > +        // Apply filters to values, prevent values filtered to null!
> > +        for(PropertyFilter filter:
> > +
> >
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyFilters()){
> > +            unfilteredValue = filter.filterProperty(key,
> unfilteredValue,
> > +                    (String k) ->
> key.equals(k)?null:get(k).orElse(null));
> > +        }
> > +        return Optional.ofNullable(unfilteredValue);
> >      }
> >
> >      @Override
> > @@ -83,7 +93,15 @@ public class DefaultConfiguration implements
> Configuration
> > {
> >                  LOG.log(Level.SEVERE, "Error adding properties from
> > PropertySource: " + propertySource +", ignoring PropertySource.",
> > e);
> >              }
> >          }
> > -        return result;
> > +        // Apply filters to values, prevent values filtered to null!
> > +        for(PropertyFilter filter:
> > +
> >
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyFilters()){
> > +            result.replaceAll((k,v) -> filter.filterProperty(k, v,
> > +                    (String k2) ->
> k2.equals(k)?null:get(k2).orElse(null)));
> > +        }
> > +        // Remove null values
> > +        return result.entrySet().parallelStream().filter((e) ->
> > e.getValue()!=null).collect(
> > +                Collectors.toMap((e) -> e.getKey(), (e) ->
> > e.getValue()));
> >      }
> >
> >      /**
> > @@ -101,7 +119,8 @@ public class DefaultConfiguration implements
> Configuration
> > {
> >      public <T> Optional<T> get(String key, Class<T> type)
> > {
> >          Optional<String> value = get(key);
> >          if (value.isPresent()) {
> > -            List<PropertyConverter<T>> converters =
> >
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyConverters(type);
> > +            List<PropertyConverter<T>> converters =
> > ServiceContext.getInstance().getService(ConfigurationContext.class)
> > +                    .get().getPropertyConverters(type);
> >              for (PropertyConverter<T> converter : converters) {
> >                  try {
> >                      T t = converter.convert(value.get());
> >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
> > ----------------------------------------------------------------------
> > diff --git
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
> > new file mode 100644
> > index 0000000..21806cd
> > --- /dev/null
> > +++
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
> > @@ -0,0 +1,178 @@
> > +/*
> > + * Licensed to the Apache Software Foundation (ASF) under one
> > + * or more contributor license agreements.  See the NOTICE file
> > + * distributed with this work for additional information
> > + * regarding copyright ownership.  The ASF licenses this file
> > + * to you under the Apache License, Version 2.0 (the
> > + * "License"); you may not use this file except in compliance
> > + * with the License.  You may obtain a copy of the License at
> > + *
> > + *  http://www.apache.org/licenses/LICENSE-2.0
> > + *
> > + * Unless required by applicable law or agreed to in writing,
> > + * software distributed under the License is distributed on an
> > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > + * KIND, either express or implied.  See the License for the
> > + * specific language governing permissions and limitations
> > + * under the License.
> > + */
> > +package org.apache.tamaya.core.internal.resource;
> > +
> > +import org.apache.tamaya.core.resources.Resource;
> > +
> > +import java.io.IOException;
> > +import java.io.InputStream;
> > +import java.net.URI;
> > +import java.net.URISyntaxException;
> > +import java.net.URL;
> > +import java.util.Objects;
> > +
> > +/**
> > + * Implementation of {@link Resource} to be loaded from the classpath.
> > + */
> > +public class ClassPathResource implements Resource {
> > +
> > +    private final String path;
> > +
> > +    private ClassLoader classLoader;
> > +
> > +
> > +    /**
> > +     * Create a new resource using the current context class loader.
> > +     *
> > +     * @param path the resource path, not null
> > +     * @see java.lang.ClassLoader#getResourceAsStream(String)
> > +     */
> > +    public ClassPathResource(String path) {
> > +        this(path, (ClassLoader) null);
> > +    }
> > +
> > +    /**
> > +     * Create a new resource using the given class loader.
> > +     *
> > +     * @param path        the resource path, not null
> > +     * @param classLoader the class loader to load the resource with,
> > +     *                    or {@code null} for the current context class
> > loader
> > +     * @see ClassLoader#getResourceAsStream(String)
> > +     */
> > +    public ClassPathResource(String path, ClassLoader classLoader) {
> > +        Objects.requireNonNull(path, "Path null");
> > +        if (path.startsWith("/")) {
> > +            path = path.substring(1);
> > +        }
> > +        this.path = path.trim();
> > +        if(classLoader==null){
> > +            classLoader =
> Thread.currentThread().getContextClassLoader();
> > +        }
> > +        if(classLoader==null){
> > +            classLoader = getClass().getClassLoader();
> > +        }
> > +        this.classLoader = classLoader;
> > +    }
> > +
> > +    /**
> > +     * @return the path for this resource.
> > +     */
> > +    public final String getPath() {
> > +        return this.path;
> > +    }
> > +
> > +    /**
> > +     * @return the ClassLoader that this resource will be accessed from.
> > +     */
> > +    public final ClassLoader getClassLoader() {
> > +        return this.classLoader;
> > +    }
> > +
> > +
> > +    /**
> > +     * Checks if the given resource is resolvable from the configured
> > classloader.
> > +     *
> > +     * @see java.lang.ClassLoader#getResource(String)
> > +     */
> > +    @Override
> > +    public boolean exists() {
> > +        return (resolveURL() != null);
> > +    }
> > +
> > +    /**
> > +     * Resolves a URL for the underlying class path resource.
> > +     *
> > +     * @return the resolved URL, or {@code null}
> > +     */
> > +    protected URL resolveURL() {
> > +        return this.classLoader.getResource(this.path);
> > +    }
> > +
> > +    /**
> > +     * This implementation opens an InputStream for the given class path
> > resource.
> > +     *
> > +     * @see java.lang.ClassLoader#getResourceAsStream(String)
> > +     * @see java.lang.Class#getResourceAsStream(String)
> > +     */
> > +    @Override
> > +    public InputStream getInputStream() throws IOException {
> > +        InputStream is =
> this.classLoader.getResourceAsStream(this.path);
> > +        if (is == null) {
> > +            throw new IOException(getName() + " does not exist");
> > +        }
> > +        return is;
> > +    }
> > +
> > +    @Override
> > +    public URI toURI() throws IOException {
> > +        try {
> > +            return resolveURL().toURI();
> > +        } catch (URISyntaxException e) {
> > +            throw new IOException(e);
> > +        }
> > +    }
> > +
> > +    @Override
> > +    public long lastModified() throws IOException {
> > +        return 0;
> > +    }
> > +
> > +    /**
> > +     * This implementation returns the name current the file that this
> class
> > path
> > +     * resource refers to.
> > +     */
> > +    @Override
> > +    public String getName() {
> > +        return "classpath:"+path;
> > +    }
> > +
> > +    /**
> > +     * This implementation returns a description that includes the
> class path
> > location.
> > +     */
> > +    @Override
> > +    public String toString() {
> > +        return "ClassPathResource[" + path + ']';
> > +    }
> > +
> > +    /**
> > +     * This implementation compares the underlying class path locations.
> > +     */
> > +    @Override
> > +    public boolean equals(Object obj) {
> > +        if (obj == this) {
> > +            return true;
> > +        }
> > +        if (obj instanceof ClassPathResource) {
> > +            ClassPathResource otherRes = (ClassPathResource) obj;
> > +            return (this.path.equals(otherRes.path) &&
> > +                    Objects.equals(this.classLoader,
> otherRes.classLoader));
> > +        }
> > +        return false;
> > +    }
> > +
> > +    /**
> > +     * This implementation returns the hash code current the underlying
> > +     * class path location.
> > +     */
> > +    @Override
> > +    public int hashCode() {
> > +        return getName().hashCode();
> > +    }
> > +
> > +}
> >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
> > ----------------------------------------------------------------------
> > diff --git
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
> > new file mode 100644
> > index 0000000..eb56c1d
> > --- /dev/null
> > +++
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
> > @@ -0,0 +1,93 @@
> > +/*
> > + * Licensed to the Apache Software Foundation (ASF) under one
> > + * or more contributor license agreements.  See the NOTICE file
> > + * distributed with this work for additional information
> > + * regarding copyright ownership.  The ASF licenses this file
> > + * to you under the Apache License, Version 2.0 (the
> > + * "License"); you may not use this file except in compliance
> > + * with the License.  You may obtain a copy of the License at
> > + *
> > + *  http://www.apache.org/licenses/LICENSE-2.0
> > + *
> > + * Unless required by applicable law or agreed to in writing,
> > + * software distributed under the License is distributed on an
> > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > + * KIND, either express or implied.  See the License for the
> > + * specific language governing permissions and limitations
> > + * under the License.
> > + */
> > +package org.apache.tamaya.core.internal.resource;
> > +
> > +import org.apache.tamaya.core.resources.Resource;
> > +import org.apache.tamaya.core.resources.ResourceLoader;
> > +
> > +import javax.annotation.Priority;
> > +import java.io.File;
> > +import java.net.URL;
> > +import java.util.ArrayList;
> > +import java.util.Collection;
> > +import java.util.Enumeration;
> > +import java.util.List;
> > +import java.util.logging.Logger;
> > +
> > +/**
> > + * Simple default implementation of the resource loader, which does only
> > support direct references to files.
> > + */
> > +@Priority(0)
> > +public class DefaultResourceLoader implements ResourceLoader {
> > +
> > +    private static final Logger LOG =
> > Logger.getLogger(DefaultResourceLoader.class.getName());
> > +
> > +    @Override
> > +    public List<Resource> getResources(ClassLoader classLoader,
> > Collection<String> expressions) {
> > +        List<Resource> resources = new ArrayList<>();
> > +        for (String expression : expressions) {
> > +            if (tryClassPath(classLoader, expression, resources) ||
> > tryFile(expression, resources) ||
> > +                    tryURL(expression, resources)) {
> > +                continue;
> > +            }
> > +            LOG.warning("Failed to resolve resource: " + expression);
> > +        }
> > +        return resources;
> > +    }
> > +
> > +    private boolean tryClassPath(ClassLoader classLoader, String
> expression,
> > List<Resource> resources) {
> > +        try {
> > +            Enumeration<URL> urls =
> classLoader.getResources(expression);
> > +            while (urls.hasMoreElements()) {
> > +                URL url = urls.nextElement();
> > +                resources.add(new URLResource(url));
> > +            }
> > +            return !resources.isEmpty();
> > +        } catch (Exception e) {
> > +            LOG.finest(() -> "Failed to load resource from CP: " +
> > expression);
> > +        }
> > +        return false;
> > +    }
> > +
> > +    private boolean tryFile(String expression, List<Resource> resources)
> > {
> > +        try {
> > +            File file = new File(expression);
> > +            if (file.exists()) {
> > +                resources.add(new FileResource(file));
> > +                return true;
> > +            }
> > +        } catch (Exception e) {
> > +            LOG.finest(() -> "Failed to load resource from file: "
> > + expression);
> > +        }
> > +        return false;
> > +    }
> > +
> > +    private boolean tryURL(String expression, List<Resource> resources)
> > {
> > +        try {
> > +            URL url = new URL(expression);
> > +            resources.add(new URLResource(url));
> > +            return true;
> > +        } catch (Exception e) {
> > +            LOG.finest(() -> "Failed to load resource from file: "
> > + expression);
> > +        }
> > +        return false;
> > +
> > +    }
> > +
> > +}
> >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
> > ----------------------------------------------------------------------
> > diff --git
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
> > new file mode 100644
> > index 0000000..e0096e5
> > --- /dev/null
> > +++
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
> > @@ -0,0 +1,162 @@
> > +/*
> > + * Licensed to the Apache Software Foundation (ASF) under one
> > + * or more contributor license agreements.  See the NOTICE file
> > + * distributed with this work for additional information
> > + * regarding copyright ownership.  The ASF licenses this file
> > + * to you under the Apache License, Version 2.0 (the
> > + * "License"); you may not use this file except in compliance
> > + * with the License.  You may obtain a copy of the License at
> > + *
> > + *  http://www.apache.org/licenses/LICENSE-2.0
> > + *
> > + * Unless required by applicable law or agreed to in writing,
> > + * software distributed under the License is distributed on an
> > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > + * KIND, either express or implied.  See the License for the
> > + * specific language governing permissions and limitations
> > + * under the License.
> > + */
> > +package org.apache.tamaya.core.internal.resource;
> > +
> > +import org.apache.tamaya.core.resources.Resource;
> > +
> > +import java.io.File;
> > +import java.io.FileInputStream;
> > +import java.io.IOException;
> > +import java.io.InputStream;
> > +import java.net.URI;
> > +import java.util.Objects;
> > +
> > +/**
> > + * Implementation of {@link org.apache.tamaya.core.resources.Resource}
> to
> > be loaded from a file.
> > + * @see java.io.File
> > + */
> > +public class FileResource implements Resource {
> > +
> > +    private final File file;
> > +
> > +    /**
> > +     * Creates a new instance.
> > +     *
> > +     * @param file a File, not null.
> > +     */
> > +    public FileResource(File file) {
> > +        this.file = Objects.requireNonNull(file, "File must not be
> > null");
> > +    }
> > +
> > +    /**
> > +     * Crreates a new instance.
> > +     *
> > +     * @param filePath a file path
> > +     */
> > +    public FileResource(String filePath) {
> > +        Objects.requireNonNull(filePath, "Path must not be null");
> > +        this.file = new File(filePath);
> > +    }
> > +
> > +
> > +    /**
> > +     * Get the file path for this resource.
> > +     */
> > +    public final String getPath() {
> > +        return this.file.getPath();
> > +    }
> > +
> > +
> > +    /**
> > +     * This implementation returns whether the underlying file exists.
> > +     *
> > +     * @see java.io.File#exists()
> > +     */
> > +    @Override
> > +    public boolean exists() {
> > +        return this.file.exists();
> > +    }
> > +
> > +    /**
> > +     * This implementation checks whether the underlying file is marked
> as
> > readable
> > +     * (and corresponds to an actual file with content, not to a
> directory).
> > +     *
> > +     * @see java.io.File#canRead()
> > +     * @see java.io.File#isDirectory()
> > +     */
> > +    @Override
> > +    public boolean isAccessible() {
> > +        return (this.file.canRead() && !this.file.isDirectory());
> > +    }
> > +
> > +    /**
> > +     * This implementation opens a FileInputStream for the underlying
> file.
> > +     *
> > +     * @see java.io.FileInputStream
> > +     */
> > +    @Override
> > +    public InputStream getInputStream() throws IOException {
> > +        return new FileInputStream(this.file);
> > +    }
> > +
> > +    /**
> > +     * This implementation returns a URI for the underlying file.
> > +     *
> > +     * @see java.io.File#toURI()
> > +     */
> > +    @Override
> > +    public URI toURI() throws IOException {
> > +        return this.file.toURI();
> > +    }
> > +
> > +    /**
> > +     * Returns the underlying File's length.
> > +     */
> > +    @Override
> > +    public long length() throws IOException {
> > +        return this.file.length();
> > +    }
> > +
> > +    @Override
> > +    public long lastModified() throws IOException {
> > +        return file.lastModified();
> > +    }
> > +
> > +    /**
> > +     * Returns the name of the current file.
> > +     *
> > +     * @see java.io.File#getName()
> > +     */
> > +    @Override
> > +    public String getName() {
> > +        return this.file.getName();
> > +    }
> > +
> > +    /**
> > +     * Returns a description that includes the absolute
> > +     * path of the current file.
> > +     *
> > +     * @see java.io.File#getAbsolutePath()
> > +     */
> > +    @Override
> > +    public String toString() {
> > +        return "File [" + this.file.getAbsolutePath() +
> > "]";
> > +    }
> > +
> > +
> > +    // implementation current WritableResource
> > +
> > +    /**
> > +     * Compares the underlying Files.
> > +     */
> > +    @Override
> > +    public boolean equals(Object obj) {
> > +        return (obj == this ||
> > +                (obj instanceof FileResource &&
> > this.file.equals(((FileResource) obj).file)));
> > +    }
> > +
> > +    /**
> > +     * Returns hash code current the underlying File reference.
> > +     */
> > +    @Override
> > +    public int hashCode() {
> > +        return this.file.hashCode();
> > +    }
> > +
> > +}
> >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
> > ----------------------------------------------------------------------
> > diff --git
> >
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
> > new file mode 100644
> > index 0000000..09510b4
> > --- /dev/null
> > +++
> >
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
> > @@ -0,0 +1,117 @@
> > +/*
> > + * Licensed to the Apache Software Foundation (ASF) under one
> > + * or more contributor license agreements.  See the NOTICE file
> > + * distributed with this work for additional information
> > + * regarding copyright ownership.  The ASF licenses this file
> > + * to you under the Apache License, Version 2.0 (the
> > + * "License"); you may not use this file except in compliance
> > + * with the License.  You may obtain a copy of the License at
> > + *
> > + *  http://www.apache.org/licenses/LICENSE-2.0
> > + *
> > + * Unless required by applicable law or agreed to in writing,
> > + * software distributed under the License is distributed on an
> > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > + * KIND, either express or implied.  See the License for the
> > + * specific language governing permissions and limitations
> > + * under the License.
> > + */
> > +package org.apache.tamaya.core.internal.resource;
> > +
> > +import org.apache.tamaya.core.resources.Resource;
> > +
> > +import java.io.IOException;
> > +import java.io.InputStream;
> > +import java.net.URI;
> > +import java.util.Objects;
> > +
> > +/**
> > + * Simple Resource encapsulating an InputStream.
> > + */
> > +public class InputStreamResource implements Resource {
> > +
> > +    /** The InputStream. */
> > +    private final InputStream inputStream;
> > +    /** The read flag. */
> > +    private boolean read = false;
> > +    /** The name of the resource. */
> > +    private String name;
> > +
> > +
> > +    /**
> > +     * Create a new InputStreamResource.
> > +     *
> > +     * @param inputStream the InputStream to use
> > +     */
> > +    public InputStreamResource(InputStream inputStream) {
> > +        this(inputStream, "InputStream:");
> > +    }
> > +
> > +    /**
> > +     * Create a new InputStreamResource.
> > +     *
> > +     * @param inputStream the InputStream to use
> > +     * @param name where the InputStream comes from
> > +     */
> > +    public InputStreamResource(InputStream inputStream, String name) {
> > +        this.inputStream = Objects.requireNonNull(inputStream);
> > +        this.name = (name != null ? name : "InputStream");
> > +    }
> > +
> > +
> > +    /**
> > +     * This implementation always returns {@code true}.
> > +     */
> > +    @Override
> > +    public boolean exists() {
> > +        return true;
> > +    }
> > +
> > +    @Override
> > +    public URI toURI() throws IOException {
> > +        throw new IOException("URI not available.");
> > +    }
> > +
> > +    @Override
> > +    public long lastModified() throws IOException {
> > +        throw new IOException("lastModified not available.");
> > +    }
> > +
> > +    /**
> > +     * Accesses the input stream. Hereby the input stream can only
> accessed
> > once.
> > +     */
> > +    @Override
> > +    public InputStream getInputStream() throws IOException {
> > +        if (this.read) {
> > +            throw new IllegalStateException("InputStream can only be
> read
> > once!");
> > +        }
> > +        this.read = true;
> > +        return this.inputStream;
> > +    }
> > +
> > +    /**
> > +     * This implementation returns the passed-in description, if any.
> > +     */
> > +    public String toString() {
> > +        return this.name != null ? this.name : super.toString();
> > +    }
> > +
> > +
> > +    /**
> > +     * Compares the underlying InputStream.
> > +     */
> > +    @Override
> > +    public boolean equals(Object obj) {
> > +        return (obj == this ||
> > +                (obj instanceof InputStreamResource &&
> > ((InputStreamResource) obj).inputStream.equals(this.inputStream)));
> > +    }
> > +
> > +    /**
> > +     * This implementation returns the hash code current the underlying
> > InputStream.
> > +     */
> > +    @Override
> > +    public int hashCode() {
> > +        return this.inputStream.hashCode();
> > +    }
> > +
> > +}
> >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
> > ----------------------------------------------------------------------
> > diff --git
> >
> a/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
> >
> b/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
> > new file mode 100644
> > index 0000000..4da6c53
> > --- /dev/null
> > +++
> >
> b/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
> > @@ -0,0 +1,37 @@
> > +/*
> > + * Licensed to the Apache Software Foundation (ASF) under one
> > + * or more contributor license agreements.  See the NOTICE file
> > + * distributed with this work for additional information
> > + * regarding copyright ownership.  The ASF licenses this file
> > + * to you under the Apache License, Version 2.0 (the
> > + * "License"); you may not use this file except in compliance
> > + * with the License.  You may obtain a copy of the License at
> > + *
> > + *  http://www.apache.org/licenses/LICENSE-2.0
> > + *
> > + * Unless required by applicable law or agreed to in writing,
> > + * software distributed under the License is distributed on an
> > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > + * KIND, either express or implied.  See the License for the
> > + * specific language governing permissions and limitations
> > + * under the License.
> > + */
> > +package org.apache.tamaya.core.resources;
> > +
> > +import java.io.IOException;
> > +import java.io.InputStream;
> > +
> > +/**
> > + * Simple interface for a component that provides data based on an
> InputStream.
> > + */
> > +@FunctionalInterface
> > +public interface InputStreamSupplier {
> > +
> > +    /**
> > +     * Access the input stream.
> > +     * @return the input stream for use.
> > +     * @throws IOException i the input stream could not be obtained.
> > +     */
> > +    InputStream getInputStream() throws IOException;
> > +
> > +}
> >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
> > ----------------------------------------------------------------------
> > diff --git
> a/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
> > b/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
> > new file mode 100644
> > index 0000000..31c679d
> > --- /dev/null
> > +++ b/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
> > @@ -0,0 +1,115 @@
> > +/*
> > + * Licensed to the Apache Software Foundation (ASF) under one
> > + * or more contributor license agreements.  See the NOTICE file
> > + * distributed with this work for additional information
> > + * regarding copyright ownership.  The ASF licenses this file
> > + * to you under the Apache License, Version 2.0 (the
> > + * "License"); you may not use this file except in compliance
> > + * with the License.  You may obtain a copy of the License at
> > + *
> > + *  http://www.apache.org/licenses/LICENSE-2.0
> > + *
> > + * Unless required by applicable law or agreed to in writing,
> > + * software distributed under the License is distributed on an
> > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > + * KIND, either express or implied.  See the License for the
> > + * specific language governing permissions and limitations
> > + * under the License.
> > + */
> > +package org.apache.tamaya.core.resources;
> > +
> > +import java.io.File;
> > +import java.io.IOException;
> > +import java.io.InputStream;
> > +import java.net.URI;
> > +import java.net.URL;
> > +import java.util.Objects;
> > +
> > +/**
> > + * Interface for an abstract resource. The effective resource
> implementation
> > can be completely arbitrary.
> > + * By default files, classpath resources and URLs are supported, but
> alternate
> > implementations are possible.
> > + *
> > + * @see #getInputStream()
> > + * @see #toURI()
> > + */
> > +public interface Resource extends InputStreamSupplier {
> > +
> > +    /**
> > +     * Return whether this resource actually exists. Depending on the
> resource
> > this can delegate to
> > +     * {@link java.io.File#exists()} or whatever may be appropriate to
> > check accessibility of the resource.
> > +     */
> > +    default boolean exists() {
> > +        // Try to open a file first, if that fails try to open the
> stream...
> > +        try {
> > +            return new File(toURI()).exists();
> > +        } catch (IOException ex) {
> > +            // Fallback
> > +            try {
> > +                InputStream is = getInputStream();
> > +                is.close();
> > +                return true;
> > +            } catch (Exception e) {
> > +                // ignore, just return false for non existing
> > +                return false;
> > +            }
> > +        }
> > +    }
> > +
> > +    /**
> > +     * Checks whether the resource is accessible, meaning {@link
> > #getInputStream()} should return a InputStream for reading the
> > +     * resource's content.
> > +     *
> > +     * @see #getInputStream()
> > +     */
> > +    default boolean isAccessible() {
> > +        return true;
> > +    }
> > +
> > +    /**
> > +     * Returns the resource as an URI.
> > +     *
> > +     * @throws IOException if the resource cannot be resolved as URI.
> > +     */
> > +    URI toURI() throws IOException;
> > +
> > +    /**
> > +     * Determines the length for this resource.
> > +     *
> > +     * @throws IOException if the resource is not readable.
> > +     */
> > +    default long length() throws IOException {
> > +        try(InputStream is = this.getInputStream();) {
> > +            Objects.requireNonNull(is, "resource not available");
> > +            long length = 0;
> > +            byte[] buf = new byte[256];
> > +            int bytesRead;
> > +            while ((bytesRead = is.read(buf)) > 0) {
> > +                length += bytesRead;
> > +            }
> > +            return length;
> > +        }
> > +    }
> > +
> > +    /**
> > +     * Determine the last-modified timestamp for a resource, as UTC ms
> > timestamp
> > +     *
> > +     * @throws IOException if the resource is not accessible.
> > +     */
> > +    default long lastModified() throws IOException{
> > +        return new File(toURI()).lastModified();
> > +    }
> > +
> > +    /**
> > +     * Get a name for the resource. The name should be identifying the
> resource
> > and also
> > +     * never change, so it must be eligible for hashcode/equals
> > implementations.
> > +     */
> > +    default String getName() {
> > +        try {
> > +            return toURI().toString();
> > +        } catch (Exception e) {
> > +            return toString();
> > +        }
> > +    }
> > +
> > +
> > +}
> > \ No newline at end of file
> >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
> > ----------------------------------------------------------------------
> > diff --git
> > a/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
> > b/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
> > new file mode 100644
> > index 0000000..5aff10a
> > --- /dev/null
> > +++
> b/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
> > @@ -0,0 +1,91 @@
> > +/*
> > + * Licensed to the Apache Software Foundation (ASF) under one
> > + * or more contributor license agreements.  See the NOTICE file
> > + * distributed with this work for additional information
> > + * regarding copyright ownership.  The ASF licenses this file
> > + * to you under the Apache License, Version 2.0 (the
> > + * "License"); you may not use this file except in compliance
> > + * with the License.  You may obtain a copy of the License at
> > + *
> > + *  http://www.apache.org/licenses/LICENSE-2.0
> > + *
> > + * Unless required by applicable law or agreed to in writing,
> > + * software distributed under the License is distributed on an
> > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > + * KIND, either express or implied.  See the License for the
> > + * specific language governing permissions and limitations
> > + * under the License.
> > + */
> > +package org.apache.tamaya.core.resources;
> > +
> > +import java.util.Arrays;
> > +import java.util.Collection;
> > +import java.util.List;
> > +
> > +/**
> > + * Interface to be implemented by modules. By default only direct
> file/resource
> > resolution is supported, whereas
> > + * extension modules may add functionality to perform ant styled pattern
> > resolution of resources.
> > + */
> > +public interface ResourceLoader {
> > +
> > +    /**
> > +     * Resolves resource expressions to a list of {@link
> > org.apache.tamaya.core.resources.Resource}s. Hereby
> > +     * the ordering of resources matches the input of the resolved
> expressions.
> > Nevertheless be aware that
> > +     * there is no determined ordering of resources located within a
> > classloader.
> > +     *
> > +     * @param expressions the expressions to be resolved, not empty.
> > +     * @return the corresponding collection of current {@link
> > org.apache.tamaya.core.resources.Resource}s found, never
> > +     * null.
> > +     * .
> > +     */
> > +    default Collection<Resource> getResources(Collection<String>
> > expressions) {
> > +        ClassLoader cl = Thread.currentThread().getContextClassLoader();
> > +        if (cl == null) {
> > +            cl = getClass().getClassLoader();
> > +        }
> > +        return getResources(cl, expressions);
> > +    }
> > +
> > +    /**
> > +     * Resolves resource expressions to a list of {@link
> > org.apache.tamaya.core.resources.Resource}s. Hereby
> > +     * the ordering of resources matches the input of the resolved
> expressions.
> > Nevertheless be aware that
> > +     * there is no determined ordering of resources located within a
> > classloader.
> > +     *
> > +     * @param expressions the expressions to be resolved, not empty.
> > +     * @return the corresponding collection of current {@link
> > org.apache.tamaya.core.resources.Resource}s found, never
> > +     * null.
> > +     * .
> > +     */
> > +    default Collection<Resource> getResources(String... expressions)
> > {
> > +        return getResources(Arrays.asList(expressions));
> > +    }
> > +
> > +    /**
> > +     * Resolves resource expressions to a list of {@link
> > org.apache.tamaya.core.resources.Resource}s, considerubg
> > +     * the given classloader for classloader dependent resources. Hereby
> > +     * the ordering of resources matches the input of the resolved
> expressions.
> > Nevertheless be aware that
> > +     * there is no determined ordering of resources located within a
> > classloader.
> > +     *
> > +     * @param expressions the expressions to be resolved, not empty.
> > +     * @return the corresponding collection of current {@link
> > org.apache.tamaya.core.resources.Resource}s found, never
> > +     * null.
> > +     * .
> > +     */
> > +    default Collection<Resource> getResources(ClassLoader classLoader,
> > String... expressions){
> > +        return getResources(classLoader, Arrays.asList(expressions));
> > +    }
> > +
> > +    /**
> > +     * Resolves resource expressions to a list of {@link
> > org.apache.tamaya.core.resources.Resource}s, considerubg
> > +     * the given classloader for classloader dependent resources. Hereby
> > +     * the ordering of resources matches the input of the resolved
> expressions.
> > Nevertheless be aware that
> > +     * there is no determined ordering of resources located within a
> > classloader.
> > +     *
> > +     * @param expressions the expressions to be resolved, not empty.
> > +     * @return the corresponding collection of current {@link
> > org.apache.tamaya.core.resources.Resource}s found, never
> > +     * null.
> > +     * .
> > +     */
> > +    Collection<Resource> getResources(ClassLoader classLoader,
> > Collection<String> expressions);
> > +
> > +}
> >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> > ----------------------------------------------------------------------
> > diff --git
> a/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> > b/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> > index be1eadb..9c7b894 100644
> > --- a/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> > +++ b/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> > @@ -41,6 +41,12 @@ public class ConfigurationTest {
> >          assertEquals("Lukas",
> > Configuration.current().get("name3").get());  // oderridden default
> >          assertEquals("Sereina",
> > Configuration.current().get("name4").get()); // final only
> >          assertEquals("Benjamin",
> > Configuration.current().get("name5").get()); // final only
> > +
> > +        System.out.println("name : " +
> > Configuration.current().get("name").get());
> > +        System.out.println("name2: " +
> > Configuration.current().get("name2").get());
> > +        System.out.println("name3: " +
> > Configuration.current().get("name3").get());
> > +        System.out.println("name4: " +
> > Configuration.current().get("name4").get());
> > +        System.out.println("name5: " +
> > Configuration.current().get("name5").get());
> >      }
> >
> >
> >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
> > ----------------------------------------------------------------------
> > diff --git
> >
> a/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
> >
> b/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
> > deleted file mode 100644
> > index 51cc2dc..0000000
> > ---
> >
> a/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
> > +++ /dev/null
> > @@ -1,70 +0,0 @@
> > -/*
> > - * Licensed to the Apache Software Foundation (ASF) under one
> > - * or more contributor license agreements.  See the NOTICE file
> > - * distributed with this work for additional information
> > - * regarding copyright ownership.  The ASF licenses this file
> > - * to you under the Apache License, Version 2.0 (the
> > - * "License"); you may not use this file except in compliance
> > - * with the License.  You may obtain a copy of the License at
> > - *
> > - * http://www.apache.org/licenses/LICENSE-2.0
> > - *
> > - * Unless required by applicable law or agreed to in writing,
> > - * software distributed under the License is distributed on an
> > - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > - * KIND, either express or implied.  See the License for the
> > - * specific language governing permissions and limitations
> > - * under the License.
> > - */
> > -package org.apache.tamaya.core.test.propertysource;
> > -
> > -import org.apache.tamaya.core.propertysource.DefaultOrdinal;
> > -import org.apache.tamaya.core.propertysource.EnvironmentPropertySource;
> > -import org.junit.Assert;
> > -import org.junit.Test;
> > -
> > -import java.util.Map;
> > -import java.util.Optional;
> > -
> > -public class EnvironmentPropertySourceTest {
> > -
> > -    private EnvironmentPropertySource propertySource = new
> > EnvironmentPropertySource();
> > -
> > -
> > -    @Test
> > -    public void testGetOrdinal() {
> > -        Assert.assertEquals(DefaultOrdinal.ENVIRONMENT_PROPERTIES,
> > propertySource.getOrdinal());
> > -    }
> > -
> > -    @Test
> > -    public void testGet() {
> > -        String environmentPropertyToCheck =
> > System.getenv().keySet().iterator().next();
> > -
> > -        Optional<String> value =
> > propertySource.get(environmentPropertyToCheck);
> > -        Assert.assertTrue(value.isPresent());
> > -        Assert.assertEquals(System.getenv(environmentPropertyToCheck),
> > value.get());
> > -    }
> > -
> > -    @Test
> > -    public void testGetProperties() {
> > -        Map<String, String> environmentProperties = System.getenv();
> > -
> > -        Assert.assertEquals(environmentProperties.size(),
> > propertySource.getProperties().size());
> > -
> > -        for (Map.Entry<String, String> propertySourceEntry :
> > propertySource.getProperties().entrySet()) {
> > -            Assert.assertEquals("Entry values for key '" +
> > propertySourceEntry.getKey() + "' do not match",
> > -
> > environmentProperties.get(propertySourceEntry.getKey()),
> > propertySourceEntry.getValue());
> > -        }
> > -
> > -        // modification is not allowed
> > -        try {
> > -            propertySource.getProperties().put("add.new.keys",
> > "must throw exception");
> > -            Assert.fail(UnsupportedOperationException.class.getName() +
> "
> > expected");
> > -        }
> > -        catch (UnsupportedOperationException e) {
> > -            // expected -> all is fine
> > -        }
> > -    }
> > -
> > -
> > -}
> >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
> > ----------------------------------------------------------------------
> > diff --git
> >
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
> >
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
> > new file mode 100644
> > index 0000000..5fa90b1
> > --- /dev/null
> > +++
> >
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
> > @@ -0,0 +1,32 @@
> > +/*
> > + * Licensed to the Apache Software Foundation (ASF) under one
> > + * or more contributor license agreements.  See the NOTICE file
> > + * distributed with this work for additional information
> > + * regarding copyright ownership.  The ASF licenses this file
> > + * to you under the Apache License, Version 2.0 (the
> > + * "License"); you may not use this file except in compliance
> > + * with the License.  You may obtain a copy of the License at
> > + *
> > + *  http://www.apache.org/licenses/LICENSE-2.0
> > + *
> > + * Unless required by applicable law or agreed to in writing,
> > + * software distributed under the License is distributed on an
> > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > + * KIND, either express or implied.  See the License for the
> > + * specific language governing permissions and limitations
> > + * under the License.
> > + */
> > +package org.apache.tamaya.core.testdata;
> > +
> > +import org.apache.tamaya.core.PathBasedPropertySourceProvider;
> > +import org.apache.tamaya.core.formats.PropertiesFormat;
> > +
> > +/**
> > + * Test provider reading properties from
> classpath:cfg/defaults/**.properties.
> > + */
> > +public class TestPropertyDefaultSourceProvider extends
> > PathBasedPropertySourceProvider{
> > +
> > +    public TestPropertyDefaultSourceProvider() {
> > +        super("default-testdata-properties", new
> > PropertiesFormat(100), "classpath:cfg/defaults/**/*.properties");
> > +    }
> > +}
> >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
> > ----------------------------------------------------------------------
> > diff --git
> >
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
> >
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
> > deleted file mode 100644
> > index d1314aa..0000000
> > ---
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
> > +++ /dev/null
> > @@ -1,55 +0,0 @@
> > -/*
> > - * Licensed to the Apache Software Foundation (ASF) under one
> > - * or more contributor license agreements.  See the NOTICE file
> > - * distributed with this work for additional information
> > - * regarding copyright ownership.  The ASF licenses this file
> > - * to you under the Apache License, Version 2.0 (the
> > - * "License"); you may not use this file except in compliance
> > - * with the License.  You may obtain a copy of the License at
> > - *
> > - *  http://www.apache.org/licenses/LICENSE-2.0
> > - *
> > - * Unless required by applicable law or agreed to in writing,
> > - * software distributed under the License is distributed on an
> > - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > - * KIND, either express or implied.  See the License for the
> > - * specific language governing permissions and limitations
> > - * under the License.
> > - */
> > -package org.apache.tamaya.core.testdata;
> > -
> > -import java.util.HashMap;
> > -import java.util.Map;
> > -
> > -import org.apache.tamaya.core.propertysource.BasePropertySource;
> > -
> > -/**
> > - * Test provider reading properties from
> classpath:cfg/final/**.properties.
> > - */
> > -public class TestPropertySource extends BasePropertySource {
> > -
> > -    private static final Map<String, String> VALUES;
> > -    static {
> > -        VALUES = new HashMap<String, String>();
> > -        VALUES.put("name", "Robin");
> > -        VALUES.put("name2", "Sabine");
> > -        VALUES.put("name3", "Lukas");
> > -        VALUES.put("name4", "Sereina");
> > -        VALUES.put("name5", "Benjamin");
> > -    }
> > -
> > -
> > -    public TestPropertySource() {
> > -        initialzeOrdinal(100);
> > -    }
> > -
> > -    @Override
> > -    public String getName() {
> > -        return "TestPropertySource";
> > -    }
> > -
> > -    @Override
> > -    public Map<String, String> getProperties() {
> > -        return VALUES;
> > -    }
> > -}
> >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
> > ----------------------------------------------------------------------
> > diff --git
> >
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
> >
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
> > new file mode 100644
> > index 0000000..beafbf9
> > --- /dev/null
> > +++
> >
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
> > @@ -0,0 +1,32 @@
> > +/*
> > + * Licensed to the Apache Software Foundation (ASF) under one
> > + * or more contributor license agreements.  See the NOTICE file
> > + * distributed with this work for additional information
> > + * regarding copyright ownership.  The ASF licenses this file
> > + * to you under the Apache License, Version 2.0 (the
> > + * "License"); you may not use this file except in compliance
> > + * with the License.  You may obtain a copy of the License at
> > + *
> > + *  http://www.apache.org/licenses/LICENSE-2.0
> > + *
> > + * Unless required by applicable law or agreed to in writing,
> > + * software distributed under the License is distributed on an
> > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > + * KIND, either express or implied.  See the License for the
> > + * specific language governing permissions and limitations
> > + * under the License.
> > + */
> > +package org.apache.tamaya.core.testdata;
> > +
> > +import org.apache.tamaya.core.PathBasedPropertySourceProvider;
> > +import org.apache.tamaya.core.formats.PropertiesFormat;
> > +
> > +/**
> > + * Test provider reading properties from
> classpath:cfg/final/**.properties.
> > + */
> > +public class TestPropertySourceProvider extends
> > PathBasedPropertySourceProvider{
> > +
> > +    public TestPropertySourceProvider() {
> > +        super("final-testdata-properties", new PropertiesFormat(200),
> > "classpath:cfg/final/**/*.properties");
> > +    }
> > +}
> >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
> > ----------------------------------------------------------------------
> > diff --git
> >
> a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
> >
> b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
> > deleted file mode 100644
> > index e6f7fad..0000000
> > ---
> >
> a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
> > +++ /dev/null
> > @@ -1,19 +0,0 @@
> > -#
> > -# Licensed to the Apache Software Foundation (ASF) under one
> > -# or more contributor license agreements.  See the NOTICE file
> > -# distributed with this work for additional information
> > -# regarding copyright ownership.  The ASF licenses this file
> > -# to you under the Apache License, Version 2.0 (the
> > -# "License"); you may not use this file except in compliance
> > -# with the License.  You may obtain a copy current the License at
> > -#
> > -#    http://www.apache.org/licenses/LICENSE-2.0
> > -#
> > -# Unless required by applicable law or agreed to in writing,
> > -# software distributed under the License is distributed on an
> > -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > -# KIND, either express or implied.  See the License for the
> > -# specific language governing permissions and limitations
> > -# under the License.
> > -#
> > -org.apache.tamaya.core.testdata.TestPropertySource
> > \ No newline at end of file
> >
> >
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
> > ----------------------------------------------------------------------
> > diff --git
> >
> a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
> >
> b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
> > new file mode 100644
> > index 0000000..9db0ef4
> > --- /dev/null
> > +++
> >
> b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
> > @@ -0,0 +1,20 @@
> > +#
> > +# Licensed to the Apache Software Foundation (ASF) under one
> > +# or more contributor license agreements.  See the NOTICE file
> > +# distributed with this work for additional information
> > +# regarding copyright ownership.  The ASF licenses this file
> > +# to you under the Apache License, Version 2.0 (the
> > +# "License"); you may not use this file except in compliance
> > +# with the License.  You may obtain a copy current the License at
> > +#
> > +#    http://www.apache.org/licenses/LICENSE-2.0
> > +#
> > +# Unless required by applicable law or agreed to in writing,
> > +# software distributed under the License is distributed on an
> > +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > +# KIND, either express or implied.  See the License for the
> > +# specific language governing permissions and limitations
> > +# under the License.
> > +#
> > +org.apache.tamaya.core.testdata.TestPropertyDefaultSourceProvider
> > +org.apache.tamaya.core.testdata.TestPropertySourceProvider
> > \ No newline at end of file
> >
>



-- 
*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 <%2B41-76%20344%2062%2079>*

Re: [2/4] incubator-tamaya git commit: TAMAYA-42, 43, 44: Readded non Spring related parts. Simplified resource API. Readded other tests.

Posted by Mark Struberg <st...@yahoo.de>.
Anatole, WHY do we need all of this?

It is NOWHERE used!

Why do we add 21 classes which don't provide anything useful to the project?
There was even a VOTE that we should keep it simple and just do the things we need.

I really don't get it. Is our goal to create a lightweight but flexible configuration system or is our goal to become big and fat?


Maybe it makes sense but if so then please explain it to us.


1.) Why do we read in a specific format? 

All the system is handling String/String and only in the last step it *probably* gets converted into a target Type. I fail to see the benefit. Please explain it to us.

2.) Why do we need all the Resource implementations?

Java provides Resource handling out of the box. Again: we don't need any scripting. So why add some handling for dynamic scenarios which we do not have? This is basically a copy of Spring.io. But we simply don't have anything scripted in XML as Spring does. So why should we add it?


I'm really tired of seeing code all over the place which is not helpful for the project. Please don't add things we don't really need.


LieGrue,
strub







> On Sunday, 4 January 2015, 2:52, "anatole@apache.org" <an...@apache.org> wrote:
> >T AMAYA-42,43,44: Readded non Spring related parts. Simplified resource API. 
> Readded other tests.
> 
> 
> Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo
> Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/cc237eb4
> Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/cc237eb4
> Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/cc237eb4
> 
> Branch: refs/heads/master
> Commit: cc237eb41b7d0c660261f451f47bbf07b7770c46
> Parents: 59a9e21
> Author: anatole <an...@apache.org>
> Authored: Sun Jan 4 02:17:56 2015 +0100
> Committer: anatole <an...@apache.org>
> Committed: Sun Jan 4 02:26:23 2015 +0100
> 
> ----------------------------------------------------------------------
> .../org/apache/tamaya/spi/PropertyFilter.java   |  10 +-
> .../core/PathBasedPropertySourceProvider.java   |  93 ++++++++++
> .../core/ResourcePropertySourceProvider.java    | 102 +++++++++++
> .../core/formats/ConfigurationFormat.java       |  53 ++++++
> .../tamaya/core/formats/PropertiesFormat.java   | 114 ++++++++++++
> .../core/formats/PropertiesXmlFormat.java       | 115 ++++++++++++
> .../core/internal/DefaultConfiguration.java     |  27 ++-
> .../internal/resource/ClassPathResource.java    | 178 +++++++++++++++++++
> .../resource/DefaultResourceLoader.java         |  93 ++++++++++
> .../core/internal/resource/FileResource.java    | 162 +++++++++++++++++
> .../internal/resource/InputStreamResource.java  | 117 ++++++++++++
> .../core/resources/InputStreamSupplier.java     |  37 ++++
> .../apache/tamaya/core/resources/Resource.java  | 115 ++++++++++++
> .../tamaya/core/resources/ResourceLoader.java   |  91 ++++++++++
> .../apache/tamaya/core/ConfigurationTest.java   |   6 +
> .../EnvironmentPropertySourceTest.java          |  70 --------
> .../TestPropertyDefaultSourceProvider.java      |  32 ++++
> .../core/testdata/TestPropertySource.java       |  55 ------
> .../testdata/TestPropertySourceProvider.java    |  32 ++++
> .../org.apache.tamaya.spi.PropertySource        |  19 --
> ...org.apache.tamaya.spi.PropertySourceProvider |  20 +++
> 21 files changed, 1388 insertions(+), 153 deletions(-)
> ----------------------------------------------------------------------
> 
> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> ----------------------------------------------------------------------
> diff --git a/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java 
> b/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> index 7479008..c8626fc 100644
> --- a/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> +++ b/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
> @@ -19,7 +19,7 @@
> package org.apache.tamaya.spi;
> 
> 
> -import java.util.Map;
> +import java.util.function.Function;
> 
> /**
>   * <p>Interface for filtering the current map of properties during the 
> evaluation of the chain of PropertySources.
> @@ -27,7 +27,7 @@ import java.util.Map;
>   * hereby is defined by the corresponding {@code @Priority} 
> annotation.</p>
>   * <p>Filters </p>
>   */
> -public interface PropertyFilter<T>{
> +public interface PropertyFilter{
> 
>      /**
>       * <p>Maps the current {@code valueToBeFiltered} value to a new 
> value. The resulting value will be used as the result
> @@ -44,10 +44,10 @@ public interface PropertyFilter<T>{
>       *
>       * @param key the key accessed, not null.
>       * @param valueToBeFiltered the value to be filtered, not null.
> -     * @param currentMap the current input property map, not null. Can be used 
> for resolution of the filtered value
> -     *                   or as datasource for additional meta-information, such 
> as categories, sensitivity etc.
> +     * @param propertyValueProvider accessor for reading additional (eg 
> metadata) properties to perform correct
> +     *                              filtering, never null.
>       * @return the filtered map, never null.
>       */
> -    String filterProperty(String key, String valueToBeFiltered, 
> Map<String,String> currentMap);
> +    String filterProperty(String key, String valueToBeFiltered, 
> Function<String,String> propertyValueProvider);
> 
> }
> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
> ----------------------------------------------------------------------
> diff --git 
> a/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java 
> b/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
> new file mode 100644
> index 0000000..31dbf4b
> --- /dev/null
> +++ 
> b/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
> @@ -0,0 +1,93 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements.  See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership.  The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License.  You may obtain a copy of the License at
> + *
> + *  http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied.  See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + */
> +package org.apache.tamaya.core;
> +
> +import org.apache.tamaya.core.formats.ConfigurationFormat;
> +import org.apache.tamaya.core.resources.Resource;
> +import org.apache.tamaya.core.resources.ResourceLoader;
> +import org.apache.tamaya.spi.PropertySource;
> +import org.apache.tamaya.spi.PropertySourceProvider;
> +import org.apache.tamaya.spi.ServiceContext;
> +
> +import java.util.ArrayList;
> +import java.util.Arrays;
> +import java.util.Collection;
> +import java.util.List;
> +import java.util.Objects;
> +import java.util.logging.Level;
> +import java.util.logging.Logger;
> +
> +/**
> + * Implementation of a {@link PropertySourceProvider} that reads 
> configuration from some given resource paths
> + * and using the given formats. The resource path are resolved using the 
> current
> + * {@link org.apache.tamaya.core.resources.ResourceLoader} active.
> + */
> +public class PathBasedPropertySourceProvider implements PropertySourceProvider 
> {
> +    /** The logger used. */
> +    private static final Logger LOG = 
> Logger.getLogger(PathBasedPropertySourceProvider.class.getName());
> +    /** The property source base name, will be used for creating a useful name 
> of the
> +     * {@link org.apache.tamaya.spi.PropertySource} created. */
> +    private String sourceName;
> +    /** The config formats supported for the given location/resource paths. */
> +    private List<ConfigurationFormat> configFormats = new 
> ArrayList<>();
> +    /** The paths to be evaluated. */
> +    private List<String> paths = new ArrayList<>();
> +
> +    /**
> +     * Creates a new instance.
> +     * @param sourceName the base name of the configuration, used for creating 
> PropertySource child names.
> +     * @param formats the formats to be used, not null, not empty.
> +     * @param paths the paths to be resolved, not null, not empty.
> +     */
> +    public PathBasedPropertySourceProvider(String sourceName, 
> List<ConfigurationFormat> formats, String... paths) {
> +        this.sourceName = Objects.requireNonNull(sourceName);
> +        this.configFormats.addAll(Objects.requireNonNull(formats));
> +        this.paths.addAll(Arrays.asList(Objects.requireNonNull(paths)));
> +    }
> +
> +    /**
> +     * Creates a new instance.
> +     * @param sourceName the base name of the configuration, used for creating 
> PropertySource child names.
> +     * @param format the format to be used.
> +     * @param paths the paths to be resolved, not null, not empty.
> +     */
> +    public PathBasedPropertySourceProvider(String sourceName, 
> ConfigurationFormat format, String... paths) {
> +        this.sourceName = Objects.requireNonNull(sourceName);
> +        this.configFormats.add(Objects.requireNonNull(format));
> +        this.paths.addAll(Arrays.asList(Objects.requireNonNull(paths)));
> +    }
> +
> +    @Override
> +    public Collection<PropertySource> getPropertySources() {
> +        List<PropertySource> propertySources = new ArrayList<>();
> +        paths.forEach((path) -> {
> +            for (Resource res : 
> ServiceContext.getInstance().getService(ResourceLoader.class).get().getResources(path)) 
> {
> +                try {
> +                    for (ConfigurationFormat format : configFormats) {
> +                        
> propertySources.addAll(format.readConfiguration(sourceName, res));
> +                    }
> +                } catch (Exception e) {
> +                    LOG.log(Level.WARNING, "Failed to add resource based 
> config: " + res.getName(), e);
> +                }
> +            }
> +        });
> +        return propertySources;
> +    }
> +
> +}
> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
> ----------------------------------------------------------------------
> diff --git 
> a/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java 
> b/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
> new file mode 100644
> index 0000000..de6b578
> --- /dev/null
> +++ 
> b/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
> @@ -0,0 +1,102 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements.  See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership.  The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License.  You may obtain a copy of the License at
> + *
> + *  http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied.  See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + */
> +package org.apache.tamaya.core;
> +
> +import org.apache.tamaya.core.formats.ConfigurationFormat;
> +import org.apache.tamaya.core.resources.Resource;
> +import org.apache.tamaya.spi.PropertySource;
> +import org.apache.tamaya.spi.PropertySourceProvider;
> +
> +import java.util.ArrayList;
> +import java.util.Arrays;
> +import java.util.Collection;
> +import java.util.List;
> +import java.util.Objects;
> +import java.util.logging.Logger;
> +
> +/**
> + * Implementation of a {@link 
> org.apache.tamaya.spi.PropertySourceProvider} that is based on a single resource
> + * and a number of formats.
> + */
> +public class ResourcePropertySourceProvider implements PropertySourceProvider 
> {
> +    /** The logger used. */
> +    private static final Logger LOG = 
> Logger.getLogger(ResourcePropertySourceProvider.class.getName());
> +    /** The supported formats. */
> +    private List<ConfigurationFormat> formats = new ArrayList<>();
> +    /** The resource. */
> +    private Resource resource;
> +    /** The source name used for creating the PropertySource names. */
> +    private String sourceName;
> +
> +    /**
> +     * Creates a new instance.
> +     * @param resource the {@link 
> org.apache.tamaya.core.resources.Resource}, not null.
> +     * @param formats the supported formats, not empty.
> +     */
> +    public ResourcePropertySourceProvider(String sourceName, Resource resource, 
> ConfigurationFormat... formats) {
> +        this(sourceName, resource, Arrays.asList(formats));
> +    }
> +
> +    /**
> +     * Creates a new instance.
> +     * @param resource the {@link 
> org.apache.tamaya.core.resources.Resource}, not null.
> +     * @param formats the supported formats, not empty.
> +     */
> +    public ResourcePropertySourceProvider(String sourceName, Resource resource, 
> List<ConfigurationFormat> formats) {
> +        this.resource = Objects.requireNonNull(resource);
> +        this.sourceName = Objects.requireNonNull(sourceName);
> +        if(formats.size()==0){
> +            throw new IllegalArgumentException("Format required.");
> +        }
> +        this.formats.addAll(formats);
> +    }
> +
> +
> +    /**
> +     * Get the underlying resource.
> +     *
> +     * @return the underlying resource, never null.
> +     */
> +    public Resource getResource() {
> +        return this.resource;
> +    }
> +
> +
> +    @Override
> +    public String toString() {
> +        return "ResourcePropertySourceProvider{" +
> +                "resource=" + resource +
> +                ", formats=+" + formats +
> +                '}';
> +    }
> +
> +    @Override
> +    public Collection<PropertySource> getPropertySources() {
> +        List<PropertySource> propertySources = new ArrayList<>();
> +        for (ConfigurationFormat format : formats) {
> +            try {
> +                propertySources.addAll(format.readConfiguration(sourceName, 
> resource));
> +            } catch (Exception e) {
> +                LOG.info(() -> "Format was not matching: " + 
> format + " for resource: " + resource.getName());
> +            }
> +        }
> +        return propertySources;
> +    }
> +
> +}
> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
> ----------------------------------------------------------------------
> diff --git 
> a/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java 
> b/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
> new file mode 100644
> index 0000000..5d289bb
> --- /dev/null
> +++ b/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
> @@ -0,0 +1,53 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements.  See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership.  The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License.  You may obtain a copy of the License at
> + *
> + *  http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied.  See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + */
> +package org.apache.tamaya.core.formats;
> +
> +import org.apache.tamaya.core.resources.Resource;
> +import org.apache.tamaya.spi.PropertySource;
> +
> +import java.io.IOException;
> +import java.util.Collection;
> +
> +/**
> + * Implementations current this class encapsulate the mechanism how to read a
> + * resource including interpreting the format correctly (e.g. xml vs.
> + * properties). In most cases file only contains entries of the same priority, 
> which would then
> + * result in only one {@link PropertySource}. Complex file formats, 
> hoiwever, may contain entries
> + * of different priorities. In this cases, each ordinal type found must be 
> returned as a separate
> + * {@link PropertySource} instance.
> + */
> +@FunctionalInterface
> +public interface ConfigurationFormat {
> +
> +    /**
> +     * Reads a list {@link org.apache.tamaya.spi.PropertySource} instances 
> from a resource, using this format.
> +     * If the configuration format only contains entries of one ordinal type, 
> normally only one single
> +     * instance of PropertySource is returned. Nevertheless custom formats may 
> contain different sections or parts,
> +     * where each part maps to a different target rdinal (eg defaults, domain 
> config and app config). In the
> +     * ladder case multiple PropertySources can be returned, each one with its 
> own ordinal and the corresponding
> +     * entries.
> +     *
> +     * @param sourceName name to be used for constructing a useful name for the 
> created
> +     *                   {@link org.apache.tamaya.spi.PropertySource} 
> instances.
> +     * @param resource   the configuration resource, not null
> +     * @return the corresponding {@link 
> org.apache.tamaya.spi.PropertySource} instances, never {@code null}.
> +     */
> +    Collection<PropertySource> readConfiguration(String sourceName, 
> Resource resource) throws IOException;
> +
> +}
> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
> ----------------------------------------------------------------------
> diff --git 
> a/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java 
> b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
> new file mode 100644
> index 0000000..3584f8e
> --- /dev/null
> +++ b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
> @@ -0,0 +1,114 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements.  See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership.  The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License.  You may obtain a copy of the License at
> + *
> + *  http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied.  See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + */
> +package org.apache.tamaya.core.formats;
> +
> +import org.apache.tamaya.core.resources.Resource;
> +import org.apache.tamaya.spi.PropertySource;
> +
> +import java.io.InputStream;
> +import java.util.ArrayList;
> +import java.util.Collection;
> +import java.util.Collections;
> +import java.util.List;
> +import java.util.Map;
> +import java.util.Optional;
> +import java.util.Properties;
> +import java.util.logging.Level;
> +import java.util.logging.Logger;
> +
> +/**
> + * Implementation of a {@link 
> org.apache.tamaya.core.formats.ConfigurationFormat} for -properties files.
> + *
> + * @see java.util.Properties#load(java.io.InputStream)
> + */
> +public class PropertiesFormat implements ConfigurationFormat {
> +    /**
> +     * The logger.
> +     */
> +    private final static Logger LOG = 
> Logger.getLogger(PropertiesFormat.class.getName());
> +
> +    /**
> +     * The target ordinal.
> +     */
> +    private int ordinal;
> +
> +    /**
> +     * Creates a new format instance, hereby producing entries with the given 
> ordinal, if not overridden by the
> +     * configuration itself.
> +     * TODO document and implement override feature
> +     * @param ordinal the target ordinal.
> +     */
> +    public PropertiesFormat(int ordinal) {
> +        this.ordinal = ordinal;
> +    }
> +
> +    /**
> +     * Get the target ordinal, produced by this format.
> +     *
> +     * @return the target ordinal
> +     */
> +    public int getOrdinal() {
> +        return ordinal;
> +    }
> +
> +    @SuppressWarnings("unchecked")
> +    @Override
> +    public Collection<PropertySource> readConfiguration(String baseName, 
> Resource resource) {
> +        final String sourceName = 
> (baseName==null?"Properties:":baseName) + resource.getName();
> +        if (resource.exists()) {
> +            List<PropertySource> propertySources = new 
> ArrayList<>();
> +            try (InputStream is = resource.getInputStream()) {
> +                final Properties p = new Properties();
> +                p.load(is);
> +                propertySources.add(new PropertySource() {
> +                    @Override
> +                    public int getOrdinal() {
> +                        return ordinal;
> +                    }
> +
> +                    @Override
> +                    public String getName() {
> +                        return sourceName;
> +                    }
> +
> +                    @Override
> +                    public Optional<String> get(String key) {
> +                        return Optional.ofNullable(p.getProperty(key));
> +                    }
> +
> +                    @Override
> +                    public Map<String, String> getProperties() {
> +                        return Map.class.cast(p);
> +                    }
> +                });
> +                return propertySources;
> +            } catch (Exception e) {
> +                LOG.log(Level.FINEST, e, () -> "Failed to read config 
> from resource: " + resource);
> +            }
> +        }
> +        return Collections.emptyList();
> +    }
> +
> +    @Override
> +    public String toString() {
> +        return "PropertiesFormat{" +
> +                "ordinal=" + ordinal +
> +                '}';
> +    }
> +}
> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
> ----------------------------------------------------------------------
> diff --git 
> a/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java 
> b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
> new file mode 100644
> index 0000000..3f77810
> --- /dev/null
> +++ b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
> @@ -0,0 +1,115 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements.  See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership.  The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License.  You may obtain a copy of the License at
> + *
> + *  http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied.  See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + */
> +package org.apache.tamaya.core.formats;
> +
> +import org.apache.tamaya.core.resources.Resource;
> +import org.apache.tamaya.spi.PropertySource;
> +
> +import java.io.InputStream;
> +import java.util.ArrayList;
> +import java.util.Collection;
> +import java.util.Collections;
> +import java.util.List;
> +import java.util.Map;
> +import java.util.Optional;
> +import java.util.Properties;
> +import java.util.logging.Level;
> +import java.util.logging.Logger;
> +
> +/**
> + * Implementation of a {@link 
> org.apache.tamaya.core.formats.ConfigurationFormat} for xml property
> + * files.
> + *
> + * @see java.util.Properties#loadFromXML(java.io.InputStream)
> + */
> +public class PropertiesXmlFormat implements ConfigurationFormat {
> +    /**
> +     * The logger.
> +     */
> +    private final static Logger LOG = 
> Logger.getLogger(PropertiesXmlFormat.class.getName());
> +
> +    /**
> +     * The target ordinal.
> +     */
> +    private int ordinal;
> +
> +    /**
> +     * Creates a new format instance, producing entries for the given ordinal, 
> if not overridden by a
> +     * config entry itself.
> +     * TODO document and implement override feature
> +     * @param ordinal the target ordinal.
> +     */
> +    public PropertiesXmlFormat(int ordinal) {
> +        this.ordinal = ordinal;
> +    }
> +
> +    /**
> +     * Get the target ordinal, produced by this format.
> +     *
> +     * @return the target ordinal
> +     */
> +    public int getOrdinal() {
> +        return ordinal;
> +    }
> +
> +    @SuppressWarnings("unchecked")
> +    @Override
> +    public Collection<PropertySource> readConfiguration(String baseName, 
> Resource resource) {
> +        if (resource.exists()) {
> +            final String sourceName = 
> (baseName==null?"Properties:":baseName) + resource.getName();
> +            List<PropertySource> propertySources = new 
> ArrayList<>();
> +            try (InputStream is = resource.getInputStream()) {
> +                final Properties p = new Properties();
> +                p.loadFromXML(is);
> +                propertySources.add(new PropertySource() {
> +                    @Override
> +                    public int getOrdinal() {
> +                        return ordinal;
> +                    }
> +
> +                    @Override
> +                    public String getName() {
> +                        return sourceName;
> +                    }
> +
> +                    @Override
> +                    public Optional<String> get(String key) {
> +                        return Optional.ofNullable(p.getProperty(key));
> +                    }
> +
> +                    @Override
> +                    public Map<String, String> getProperties() {
> +                        return Map.class.cast(p);
> +                    }
> +                });
> +                return propertySources;
> +            } catch (Exception e) {
> +                LOG.log(Level.FINEST, e, () -> "Failed to read config 
> from resource: " + resource);
> +            }
> +        }
> +        return Collections.emptyList();
> +    }
> +
> +    @Override
> +    public String toString() {
> +        return "PropertiesXmlFormat{" +
> +                "ordinal=" + ordinal +
> +                '}';
> +    }
> +}
> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> ----------------------------------------------------------------------
> diff --git 
> a/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java 
> b/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> index 0a39b7d..3769e27 100644
> --- 
> a/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> +++ 
> b/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
> @@ -22,6 +22,7 @@ import org.apache.tamaya.ConfigException;
> import org.apache.tamaya.Configuration;
> import org.apache.tamaya.spi.ConfigurationContext;
> import org.apache.tamaya.spi.PropertyConverter;
> +import org.apache.tamaya.spi.PropertyFilter;
> import org.apache.tamaya.spi.PropertySource;
> import org.apache.tamaya.spi.ServiceContext;
> 
> @@ -33,6 +34,7 @@ import java.util.Map;
> import java.util.Optional;
> import java.util.logging.Level;
> import java.util.logging.Logger;
> +import java.util.stream.Collectors;
> 
> /**
>   * Implementation of the Configuration API. This class uses the current 
> {@link ConfigurationContext} to evaluate the
> @@ -56,13 +58,21 @@ public class DefaultConfiguration implements Configuration 
> {
>      @Override
>      public Optional<String> get(String key) {
>          List<PropertySource> propertySources = 
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertySources();
> +        String unfilteredValue = null;
>          for (PropertySource propertySource : propertySources) {
>              Optional<String> value = propertySource.get(key);
>              if (value.isPresent()) {
> -                return value;
> +                unfilteredValue = value.get();
> +                break;
>              }
>          }
> -        return Optional.empty();
> +        // Apply filters to values, prevent values filtered to null!
> +        for(PropertyFilter filter:
> +                
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyFilters()){
> +            unfilteredValue = filter.filterProperty(key, unfilteredValue,
> +                    (String k) -> key.equals(k)?null:get(k).orElse(null));
> +        }
> +        return Optional.ofNullable(unfilteredValue);
>      }
> 
>      @Override
> @@ -83,7 +93,15 @@ public class DefaultConfiguration implements Configuration 
> {
>                  LOG.log(Level.SEVERE, "Error adding properties from 
> PropertySource: " + propertySource +", ignoring PropertySource.", 
> e);
>              }
>          }
> -        return result;
> +        // Apply filters to values, prevent values filtered to null!
> +        for(PropertyFilter filter:
> +                
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyFilters()){
> +            result.replaceAll((k,v) -> filter.filterProperty(k, v,
> +                    (String k2) -> k2.equals(k)?null:get(k2).orElse(null)));
> +        }
> +        // Remove null values
> +        return result.entrySet().parallelStream().filter((e) -> 
> e.getValue()!=null).collect(
> +                Collectors.toMap((e) -> e.getKey(), (e) -> 
> e.getValue()));
>      }
> 
>      /**
> @@ -101,7 +119,8 @@ public class DefaultConfiguration implements Configuration 
> {
>      public <T> Optional<T> get(String key, Class<T> type) 
> {
>          Optional<String> value = get(key);
>          if (value.isPresent()) {
> -            List<PropertyConverter<T>> converters = 
> ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyConverters(type);
> +            List<PropertyConverter<T>> converters = 
> ServiceContext.getInstance().getService(ConfigurationContext.class)
> +                    .get().getPropertyConverters(type);
>              for (PropertyConverter<T> converter : converters) {
>                  try {
>                      T t = converter.convert(value.get());
> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
> ----------------------------------------------------------------------
> diff --git 
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java 
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
> new file mode 100644
> index 0000000..21806cd
> --- /dev/null
> +++ 
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
> @@ -0,0 +1,178 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements.  See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership.  The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License.  You may obtain a copy of the License at
> + *
> + *  http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied.  See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + */
> +package org.apache.tamaya.core.internal.resource;
> +
> +import org.apache.tamaya.core.resources.Resource;
> +
> +import java.io.IOException;
> +import java.io.InputStream;
> +import java.net.URI;
> +import java.net.URISyntaxException;
> +import java.net.URL;
> +import java.util.Objects;
> +
> +/**
> + * Implementation of {@link Resource} to be loaded from the classpath.
> + */
> +public class ClassPathResource implements Resource {
> +
> +    private final String path;
> +
> +    private ClassLoader classLoader;
> +
> +
> +    /**
> +     * Create a new resource using the current context class loader.
> +     *
> +     * @param path the resource path, not null
> +     * @see java.lang.ClassLoader#getResourceAsStream(String)
> +     */
> +    public ClassPathResource(String path) {
> +        this(path, (ClassLoader) null);
> +    }
> +
> +    /**
> +     * Create a new resource using the given class loader.
> +     *
> +     * @param path        the resource path, not null
> +     * @param classLoader the class loader to load the resource with,
> +     *                    or {@code null} for the current context class 
> loader
> +     * @see ClassLoader#getResourceAsStream(String)
> +     */
> +    public ClassPathResource(String path, ClassLoader classLoader) {
> +        Objects.requireNonNull(path, "Path null");
> +        if (path.startsWith("/")) {
> +            path = path.substring(1);
> +        }
> +        this.path = path.trim();
> +        if(classLoader==null){
> +            classLoader = Thread.currentThread().getContextClassLoader();
> +        }
> +        if(classLoader==null){
> +            classLoader = getClass().getClassLoader();
> +        }
> +        this.classLoader = classLoader;
> +    }
> +
> +    /**
> +     * @return the path for this resource.
> +     */
> +    public final String getPath() {
> +        return this.path;
> +    }
> +
> +    /**
> +     * @return the ClassLoader that this resource will be accessed from.
> +     */
> +    public final ClassLoader getClassLoader() {
> +        return this.classLoader;
> +    }
> +
> +
> +    /**
> +     * Checks if the given resource is resolvable from the configured 
> classloader.
> +     *
> +     * @see java.lang.ClassLoader#getResource(String)
> +     */
> +    @Override
> +    public boolean exists() {
> +        return (resolveURL() != null);
> +    }
> +
> +    /**
> +     * Resolves a URL for the underlying class path resource.
> +     *
> +     * @return the resolved URL, or {@code null}
> +     */
> +    protected URL resolveURL() {
> +        return this.classLoader.getResource(this.path);
> +    }
> +
> +    /**
> +     * This implementation opens an InputStream for the given class path 
> resource.
> +     *
> +     * @see java.lang.ClassLoader#getResourceAsStream(String)
> +     * @see java.lang.Class#getResourceAsStream(String)
> +     */
> +    @Override
> +    public InputStream getInputStream() throws IOException {
> +        InputStream is = this.classLoader.getResourceAsStream(this.path);
> +        if (is == null) {
> +            throw new IOException(getName() + " does not exist");
> +        }
> +        return is;
> +    }
> +
> +    @Override
> +    public URI toURI() throws IOException {
> +        try {
> +            return resolveURL().toURI();
> +        } catch (URISyntaxException e) {
> +            throw new IOException(e);
> +        }
> +    }
> +
> +    @Override
> +    public long lastModified() throws IOException {
> +        return 0;
> +    }
> +
> +    /**
> +     * This implementation returns the name current the file that this class 
> path
> +     * resource refers to.
> +     */
> +    @Override
> +    public String getName() {
> +        return "classpath:"+path;
> +    }
> +
> +    /**
> +     * This implementation returns a description that includes the class path 
> location.
> +     */
> +    @Override
> +    public String toString() {
> +        return "ClassPathResource[" + path + ']';
> +    }
> +
> +    /**
> +     * This implementation compares the underlying class path locations.
> +     */
> +    @Override
> +    public boolean equals(Object obj) {
> +        if (obj == this) {
> +            return true;
> +        }
> +        if (obj instanceof ClassPathResource) {
> +            ClassPathResource otherRes = (ClassPathResource) obj;
> +            return (this.path.equals(otherRes.path) &&
> +                    Objects.equals(this.classLoader, otherRes.classLoader));
> +        }
> +        return false;
> +    }
> +
> +    /**
> +     * This implementation returns the hash code current the underlying
> +     * class path location.
> +     */
> +    @Override
> +    public int hashCode() {
> +        return getName().hashCode();
> +    }
> +
> +}
> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
> ----------------------------------------------------------------------
> diff --git 
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java 
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
> new file mode 100644
> index 0000000..eb56c1d
> --- /dev/null
> +++ 
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
> @@ -0,0 +1,93 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements.  See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership.  The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License.  You may obtain a copy of the License at
> + *
> + *  http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied.  See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + */
> +package org.apache.tamaya.core.internal.resource;
> +
> +import org.apache.tamaya.core.resources.Resource;
> +import org.apache.tamaya.core.resources.ResourceLoader;
> +
> +import javax.annotation.Priority;
> +import java.io.File;
> +import java.net.URL;
> +import java.util.ArrayList;
> +import java.util.Collection;
> +import java.util.Enumeration;
> +import java.util.List;
> +import java.util.logging.Logger;
> +
> +/**
> + * Simple default implementation of the resource loader, which does only 
> support direct references to files.
> + */
> +@Priority(0)
> +public class DefaultResourceLoader implements ResourceLoader {
> +
> +    private static final Logger LOG = 
> Logger.getLogger(DefaultResourceLoader.class.getName());
> +
> +    @Override
> +    public List<Resource> getResources(ClassLoader classLoader, 
> Collection<String> expressions) {
> +        List<Resource> resources = new ArrayList<>();
> +        for (String expression : expressions) {
> +            if (tryClassPath(classLoader, expression, resources) || 
> tryFile(expression, resources) ||
> +                    tryURL(expression, resources)) {
> +                continue;
> +            }
> +            LOG.warning("Failed to resolve resource: " + expression);
> +        }
> +        return resources;
> +    }
> +
> +    private boolean tryClassPath(ClassLoader classLoader, String expression, 
> List<Resource> resources) {
> +        try {
> +            Enumeration<URL> urls = classLoader.getResources(expression);
> +            while (urls.hasMoreElements()) {
> +                URL url = urls.nextElement();
> +                resources.add(new URLResource(url));
> +            }
> +            return !resources.isEmpty();
> +        } catch (Exception e) {
> +            LOG.finest(() -> "Failed to load resource from CP: " + 
> expression);
> +        }
> +        return false;
> +    }
> +
> +    private boolean tryFile(String expression, List<Resource> resources) 
> {
> +        try {
> +            File file = new File(expression);
> +            if (file.exists()) {
> +                resources.add(new FileResource(file));
> +                return true;
> +            }
> +        } catch (Exception e) {
> +            LOG.finest(() -> "Failed to load resource from file: " 
> + expression);
> +        }
> +        return false;
> +    }
> +
> +    private boolean tryURL(String expression, List<Resource> resources) 
> {
> +        try {
> +            URL url = new URL(expression);
> +            resources.add(new URLResource(url));
> +            return true;
> +        } catch (Exception e) {
> +            LOG.finest(() -> "Failed to load resource from file: " 
> + expression);
> +        }
> +        return false;
> +
> +    }
> +
> +}
> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
> ----------------------------------------------------------------------
> diff --git 
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java 
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
> new file mode 100644
> index 0000000..e0096e5
> --- /dev/null
> +++ 
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
> @@ -0,0 +1,162 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements.  See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership.  The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License.  You may obtain a copy of the License at
> + *
> + *  http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied.  See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + */
> +package org.apache.tamaya.core.internal.resource;
> +
> +import org.apache.tamaya.core.resources.Resource;
> +
> +import java.io.File;
> +import java.io.FileInputStream;
> +import java.io.IOException;
> +import java.io.InputStream;
> +import java.net.URI;
> +import java.util.Objects;
> +
> +/**
> + * Implementation of {@link org.apache.tamaya.core.resources.Resource} to 
> be loaded from a file.
> + * @see java.io.File
> + */
> +public class FileResource implements Resource {
> +
> +    private final File file;
> +
> +    /**
> +     * Creates a new instance.
> +     *
> +     * @param file a File, not null.
> +     */
> +    public FileResource(File file) {
> +        this.file = Objects.requireNonNull(file, "File must not be 
> null");
> +    }
> +
> +    /**
> +     * Crreates a new instance.
> +     *
> +     * @param filePath a file path
> +     */
> +    public FileResource(String filePath) {
> +        Objects.requireNonNull(filePath, "Path must not be null");
> +        this.file = new File(filePath);
> +    }
> +
> +
> +    /**
> +     * Get the file path for this resource.
> +     */
> +    public final String getPath() {
> +        return this.file.getPath();
> +    }
> +
> +
> +    /**
> +     * This implementation returns whether the underlying file exists.
> +     *
> +     * @see java.io.File#exists()
> +     */
> +    @Override
> +    public boolean exists() {
> +        return this.file.exists();
> +    }
> +
> +    /**
> +     * This implementation checks whether the underlying file is marked as 
> readable
> +     * (and corresponds to an actual file with content, not to a directory).
> +     *
> +     * @see java.io.File#canRead()
> +     * @see java.io.File#isDirectory()
> +     */
> +    @Override
> +    public boolean isAccessible() {
> +        return (this.file.canRead() && !this.file.isDirectory());
> +    }
> +
> +    /**
> +     * This implementation opens a FileInputStream for the underlying file.
> +     *
> +     * @see java.io.FileInputStream
> +     */
> +    @Override
> +    public InputStream getInputStream() throws IOException {
> +        return new FileInputStream(this.file);
> +    }
> +
> +    /**
> +     * This implementation returns a URI for the underlying file.
> +     *
> +     * @see java.io.File#toURI()
> +     */
> +    @Override
> +    public URI toURI() throws IOException {
> +        return this.file.toURI();
> +    }
> +
> +    /**
> +     * Returns the underlying File's length.
> +     */
> +    @Override
> +    public long length() throws IOException {
> +        return this.file.length();
> +    }
> +
> +    @Override
> +    public long lastModified() throws IOException {
> +        return file.lastModified();
> +    }
> +
> +    /**
> +     * Returns the name of the current file.
> +     *
> +     * @see java.io.File#getName()
> +     */
> +    @Override
> +    public String getName() {
> +        return this.file.getName();
> +    }
> +
> +    /**
> +     * Returns a description that includes the absolute
> +     * path of the current file.
> +     *
> +     * @see java.io.File#getAbsolutePath()
> +     */
> +    @Override
> +    public String toString() {
> +        return "File [" + this.file.getAbsolutePath() + 
> "]";
> +    }
> +
> +
> +    // implementation current WritableResource
> +
> +    /**
> +     * Compares the underlying Files.
> +     */
> +    @Override
> +    public boolean equals(Object obj) {
> +        return (obj == this ||
> +                (obj instanceof FileResource && 
> this.file.equals(((FileResource) obj).file)));
> +    }
> +
> +    /**
> +     * Returns hash code current the underlying File reference.
> +     */
> +    @Override
> +    public int hashCode() {
> +        return this.file.hashCode();
> +    }
> +
> +}
> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
> ----------------------------------------------------------------------
> diff --git 
> a/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java 
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
> new file mode 100644
> index 0000000..09510b4
> --- /dev/null
> +++ 
> b/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
> @@ -0,0 +1,117 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements.  See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership.  The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License.  You may obtain a copy of the License at
> + *
> + *  http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied.  See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + */
> +package org.apache.tamaya.core.internal.resource;
> +
> +import org.apache.tamaya.core.resources.Resource;
> +
> +import java.io.IOException;
> +import java.io.InputStream;
> +import java.net.URI;
> +import java.util.Objects;
> +
> +/**
> + * Simple Resource encapsulating an InputStream.
> + */
> +public class InputStreamResource implements Resource {
> +
> +    /** The InputStream. */
> +    private final InputStream inputStream;
> +    /** The read flag. */
> +    private boolean read = false;
> +    /** The name of the resource. */
> +    private String name;
> +
> +
> +    /**
> +     * Create a new InputStreamResource.
> +     *
> +     * @param inputStream the InputStream to use
> +     */
> +    public InputStreamResource(InputStream inputStream) {
> +        this(inputStream, "InputStream:");
> +    }
> +
> +    /**
> +     * Create a new InputStreamResource.
> +     *
> +     * @param inputStream the InputStream to use
> +     * @param name where the InputStream comes from
> +     */
> +    public InputStreamResource(InputStream inputStream, String name) {
> +        this.inputStream = Objects.requireNonNull(inputStream);
> +        this.name = (name != null ? name : "InputStream");
> +    }
> +
> +
> +    /**
> +     * This implementation always returns {@code true}.
> +     */
> +    @Override
> +    public boolean exists() {
> +        return true;
> +    }
> +
> +    @Override
> +    public URI toURI() throws IOException {
> +        throw new IOException("URI not available.");
> +    }
> +
> +    @Override
> +    public long lastModified() throws IOException {
> +        throw new IOException("lastModified not available.");
> +    }
> +
> +    /**
> +     * Accesses the input stream. Hereby the input stream can only accessed 
> once.
> +     */
> +    @Override
> +    public InputStream getInputStream() throws IOException {
> +        if (this.read) {
> +            throw new IllegalStateException("InputStream can only be read 
> once!");
> +        }
> +        this.read = true;
> +        return this.inputStream;
> +    }
> +
> +    /**
> +     * This implementation returns the passed-in description, if any.
> +     */
> +    public String toString() {
> +        return this.name != null ? this.name : super.toString();
> +    }
> +
> +
> +    /**
> +     * Compares the underlying InputStream.
> +     */
> +    @Override
> +    public boolean equals(Object obj) {
> +        return (obj == this ||
> +                (obj instanceof InputStreamResource && 
> ((InputStreamResource) obj).inputStream.equals(this.inputStream)));
> +    }
> +
> +    /**
> +     * This implementation returns the hash code current the underlying 
> InputStream.
> +     */
> +    @Override
> +    public int hashCode() {
> +        return this.inputStream.hashCode();
> +    }
> +
> +}
> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
> ----------------------------------------------------------------------
> diff --git 
> a/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java 
> b/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
> new file mode 100644
> index 0000000..4da6c53
> --- /dev/null
> +++ 
> b/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
> @@ -0,0 +1,37 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements.  See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership.  The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License.  You may obtain a copy of the License at
> + *
> + *  http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied.  See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + */
> +package org.apache.tamaya.core.resources;
> +
> +import java.io.IOException;
> +import java.io.InputStream;
> +
> +/**
> + * Simple interface for a component that provides data based on an InputStream.
> + */
> +@FunctionalInterface
> +public interface InputStreamSupplier {
> +
> +    /**
> +     * Access the input stream.
> +     * @return the input stream for use.
> +     * @throws IOException i the input stream could not be obtained.
> +     */
> +    InputStream getInputStream() throws IOException;
> +
> +}
> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
> ----------------------------------------------------------------------
> diff --git a/core/src/main/java/org/apache/tamaya/core/resources/Resource.java 
> b/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
> new file mode 100644
> index 0000000..31c679d
> --- /dev/null
> +++ b/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
> @@ -0,0 +1,115 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements.  See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership.  The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License.  You may obtain a copy of the License at
> + *
> + *  http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied.  See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + */
> +package org.apache.tamaya.core.resources;
> +
> +import java.io.File;
> +import java.io.IOException;
> +import java.io.InputStream;
> +import java.net.URI;
> +import java.net.URL;
> +import java.util.Objects;
> +
> +/**
> + * Interface for an abstract resource. The effective resource implementation 
> can be completely arbitrary.
> + * By default files, classpath resources and URLs are supported, but alternate 
> implementations are possible.
> + *
> + * @see #getInputStream()
> + * @see #toURI()
> + */
> +public interface Resource extends InputStreamSupplier {
> +
> +    /**
> +     * Return whether this resource actually exists. Depending on the resource 
> this can delegate to
> +     * {@link java.io.File#exists()} or whatever may be appropriate to 
> check accessibility of the resource.
> +     */
> +    default boolean exists() {
> +        // Try to open a file first, if that fails try to open the stream...
> +        try {
> +            return new File(toURI()).exists();
> +        } catch (IOException ex) {
> +            // Fallback
> +            try {
> +                InputStream is = getInputStream();
> +                is.close();
> +                return true;
> +            } catch (Exception e) {
> +                // ignore, just return false for non existing
> +                return false;
> +            }
> +        }
> +    }
> +
> +    /**
> +     * Checks whether the resource is accessible, meaning {@link 
> #getInputStream()} should return a InputStream for reading the
> +     * resource's content.
> +     *
> +     * @see #getInputStream()
> +     */
> +    default boolean isAccessible() {
> +        return true;
> +    }
> +
> +    /**
> +     * Returns the resource as an URI.
> +     *
> +     * @throws IOException if the resource cannot be resolved as URI.
> +     */
> +    URI toURI() throws IOException;
> +
> +    /**
> +     * Determines the length for this resource.
> +     *
> +     * @throws IOException if the resource is not readable.
> +     */
> +    default long length() throws IOException {
> +        try(InputStream is = this.getInputStream();) {
> +            Objects.requireNonNull(is, "resource not available");
> +            long length = 0;
> +            byte[] buf = new byte[256];
> +            int bytesRead;
> +            while ((bytesRead = is.read(buf)) > 0) {
> +                length += bytesRead;
> +            }
> +            return length;
> +        }
> +    }
> +
> +    /**
> +     * Determine the last-modified timestamp for a resource, as UTC ms 
> timestamp
> +     *
> +     * @throws IOException if the resource is not accessible.
> +     */
> +    default long lastModified() throws IOException{
> +        return new File(toURI()).lastModified();
> +    }
> +
> +    /**
> +     * Get a name for the resource. The name should be identifying the resource 
> and also
> +     * never change, so it must be eligible for hashcode/equals 
> implementations.
> +     */
> +    default String getName() {
> +        try {
> +            return toURI().toString();
> +        } catch (Exception e) {
> +            return toString();
> +        }
> +    }
> +
> +
> +}
> \ No newline at end of file
> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
> ----------------------------------------------------------------------
> diff --git 
> a/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java 
> b/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
> new file mode 100644
> index 0000000..5aff10a
> --- /dev/null
> +++ b/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
> @@ -0,0 +1,91 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements.  See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership.  The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License.  You may obtain a copy of the License at
> + *
> + *  http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied.  See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + */
> +package org.apache.tamaya.core.resources;
> +
> +import java.util.Arrays;
> +import java.util.Collection;
> +import java.util.List;
> +
> +/**
> + * Interface to be implemented by modules. By default only direct file/resource 
> resolution is supported, whereas
> + * extension modules may add functionality to perform ant styled pattern 
> resolution of resources.
> + */
> +public interface ResourceLoader {
> +
> +    /**
> +     * Resolves resource expressions to a list of {@link 
> org.apache.tamaya.core.resources.Resource}s. Hereby
> +     * the ordering of resources matches the input of the resolved expressions. 
> Nevertheless be aware that
> +     * there is no determined ordering of resources located within a 
> classloader.
> +     *
> +     * @param expressions the expressions to be resolved, not empty.
> +     * @return the corresponding collection of current {@link 
> org.apache.tamaya.core.resources.Resource}s found, never
> +     * null.
> +     * .
> +     */
> +    default Collection<Resource> getResources(Collection<String> 
> expressions) {
> +        ClassLoader cl = Thread.currentThread().getContextClassLoader();
> +        if (cl == null) {
> +            cl = getClass().getClassLoader();
> +        }
> +        return getResources(cl, expressions);
> +    }
> +
> +    /**
> +     * Resolves resource expressions to a list of {@link 
> org.apache.tamaya.core.resources.Resource}s. Hereby
> +     * the ordering of resources matches the input of the resolved expressions. 
> Nevertheless be aware that
> +     * there is no determined ordering of resources located within a 
> classloader.
> +     *
> +     * @param expressions the expressions to be resolved, not empty.
> +     * @return the corresponding collection of current {@link 
> org.apache.tamaya.core.resources.Resource}s found, never
> +     * null.
> +     * .
> +     */
> +    default Collection<Resource> getResources(String... expressions) 
> {
> +        return getResources(Arrays.asList(expressions));
> +    }
> +
> +    /**
> +     * Resolves resource expressions to a list of {@link 
> org.apache.tamaya.core.resources.Resource}s, considerubg
> +     * the given classloader for classloader dependent resources. Hereby
> +     * the ordering of resources matches the input of the resolved expressions. 
> Nevertheless be aware that
> +     * there is no determined ordering of resources located within a 
> classloader.
> +     *
> +     * @param expressions the expressions to be resolved, not empty.
> +     * @return the corresponding collection of current {@link 
> org.apache.tamaya.core.resources.Resource}s found, never
> +     * null.
> +     * .
> +     */
> +    default Collection<Resource> getResources(ClassLoader classLoader, 
> String... expressions){
> +        return getResources(classLoader, Arrays.asList(expressions));
> +    }
> +
> +    /**
> +     * Resolves resource expressions to a list of {@link 
> org.apache.tamaya.core.resources.Resource}s, considerubg
> +     * the given classloader for classloader dependent resources. Hereby
> +     * the ordering of resources matches the input of the resolved expressions. 
> Nevertheless be aware that
> +     * there is no determined ordering of resources located within a 
> classloader.
> +     *
> +     * @param expressions the expressions to be resolved, not empty.
> +     * @return the corresponding collection of current {@link 
> org.apache.tamaya.core.resources.Resource}s found, never
> +     * null.
> +     * .
> +     */
> +    Collection<Resource> getResources(ClassLoader classLoader, 
> Collection<String> expressions);
> +
> +}
> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> ----------------------------------------------------------------------
> diff --git a/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java 
> b/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> index be1eadb..9c7b894 100644
> --- a/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> +++ b/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
> @@ -41,6 +41,12 @@ public class ConfigurationTest {
>          assertEquals("Lukas", 
> Configuration.current().get("name3").get());  // oderridden default
>          assertEquals("Sereina", 
> Configuration.current().get("name4").get()); // final only
>          assertEquals("Benjamin", 
> Configuration.current().get("name5").get()); // final only
> +
> +        System.out.println("name : " + 
> Configuration.current().get("name").get());
> +        System.out.println("name2: " + 
> Configuration.current().get("name2").get());
> +        System.out.println("name3: " + 
> Configuration.current().get("name3").get());
> +        System.out.println("name4: " + 
> Configuration.current().get("name4").get());
> +        System.out.println("name5: " + 
> Configuration.current().get("name5").get());
>      }
> 
> 
> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
> ----------------------------------------------------------------------
> diff --git 
> a/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java 
> b/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
> deleted file mode 100644
> index 51cc2dc..0000000
> --- 
> a/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
> +++ /dev/null
> @@ -1,70 +0,0 @@
> -/*
> - * Licensed to the Apache Software Foundation (ASF) under one
> - * or more contributor license agreements.  See the NOTICE file
> - * distributed with this work for additional information
> - * regarding copyright ownership.  The ASF licenses this file
> - * to you under the Apache License, Version 2.0 (the
> - * "License"); you may not use this file except in compliance
> - * with the License.  You may obtain a copy of the License at
> - *
> - * http://www.apache.org/licenses/LICENSE-2.0
> - *
> - * Unless required by applicable law or agreed to in writing,
> - * software distributed under the License is distributed on an
> - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> - * KIND, either express or implied.  See the License for the
> - * specific language governing permissions and limitations
> - * under the License.
> - */
> -package org.apache.tamaya.core.test.propertysource;
> -
> -import org.apache.tamaya.core.propertysource.DefaultOrdinal;
> -import org.apache.tamaya.core.propertysource.EnvironmentPropertySource;
> -import org.junit.Assert;
> -import org.junit.Test;
> -
> -import java.util.Map;
> -import java.util.Optional;
> -
> -public class EnvironmentPropertySourceTest {
> -
> -    private EnvironmentPropertySource propertySource = new 
> EnvironmentPropertySource();
> -
> -
> -    @Test
> -    public void testGetOrdinal() {
> -        Assert.assertEquals(DefaultOrdinal.ENVIRONMENT_PROPERTIES, 
> propertySource.getOrdinal());
> -    }
> -
> -    @Test
> -    public void testGet() {
> -        String environmentPropertyToCheck = 
> System.getenv().keySet().iterator().next();
> -
> -        Optional<String> value = 
> propertySource.get(environmentPropertyToCheck);
> -        Assert.assertTrue(value.isPresent());
> -        Assert.assertEquals(System.getenv(environmentPropertyToCheck), 
> value.get());
> -    }
> -
> -    @Test
> -    public void testGetProperties() {
> -        Map<String, String> environmentProperties = System.getenv();
> -
> -        Assert.assertEquals(environmentProperties.size(), 
> propertySource.getProperties().size());
> -
> -        for (Map.Entry<String, String> propertySourceEntry : 
> propertySource.getProperties().entrySet()) {
> -            Assert.assertEquals("Entry values for key '" + 
> propertySourceEntry.getKey() + "' do not match",
> -                                
> environmentProperties.get(propertySourceEntry.getKey()), 
> propertySourceEntry.getValue());
> -        }
> -
> -        // modification is not allowed
> -        try {
> -            propertySource.getProperties().put("add.new.keys", 
> "must throw exception");
> -            Assert.fail(UnsupportedOperationException.class.getName() + " 
> expected");
> -        }
> -        catch (UnsupportedOperationException e) {
> -            // expected -> all is fine
> -        }
> -    }
> -
> -
> -}
> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
> ----------------------------------------------------------------------
> diff --git 
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java 
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
> new file mode 100644
> index 0000000..5fa90b1
> --- /dev/null
> +++ 
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
> @@ -0,0 +1,32 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements.  See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership.  The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License.  You may obtain a copy of the License at
> + *
> + *  http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied.  See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + */
> +package org.apache.tamaya.core.testdata;
> +
> +import org.apache.tamaya.core.PathBasedPropertySourceProvider;
> +import org.apache.tamaya.core.formats.PropertiesFormat;
> +
> +/**
> + * Test provider reading properties from classpath:cfg/defaults/**.properties.
> + */
> +public class TestPropertyDefaultSourceProvider extends 
> PathBasedPropertySourceProvider{
> +
> +    public TestPropertyDefaultSourceProvider() {
> +        super("default-testdata-properties", new 
> PropertiesFormat(100), "classpath:cfg/defaults/**/*.properties");
> +    }
> +}
> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
> ----------------------------------------------------------------------
> diff --git 
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java 
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
> deleted file mode 100644
> index d1314aa..0000000
> --- a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
> +++ /dev/null
> @@ -1,55 +0,0 @@
> -/*
> - * Licensed to the Apache Software Foundation (ASF) under one
> - * or more contributor license agreements.  See the NOTICE file
> - * distributed with this work for additional information
> - * regarding copyright ownership.  The ASF licenses this file
> - * to you under the Apache License, Version 2.0 (the
> - * "License"); you may not use this file except in compliance
> - * with the License.  You may obtain a copy of the License at
> - *
> - *  http://www.apache.org/licenses/LICENSE-2.0
> - *
> - * Unless required by applicable law or agreed to in writing,
> - * software distributed under the License is distributed on an
> - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> - * KIND, either express or implied.  See the License for the
> - * specific language governing permissions and limitations
> - * under the License.
> - */
> -package org.apache.tamaya.core.testdata;
> -
> -import java.util.HashMap;
> -import java.util.Map;
> -
> -import org.apache.tamaya.core.propertysource.BasePropertySource;
> -
> -/**
> - * Test provider reading properties from classpath:cfg/final/**.properties.
> - */
> -public class TestPropertySource extends BasePropertySource {
> -
> -    private static final Map<String, String> VALUES;
> -    static {
> -        VALUES = new HashMap<String, String>();
> -        VALUES.put("name", "Robin");
> -        VALUES.put("name2", "Sabine");
> -        VALUES.put("name3", "Lukas");
> -        VALUES.put("name4", "Sereina");
> -        VALUES.put("name5", "Benjamin");
> -    }
> -
> -
> -    public TestPropertySource() {
> -        initialzeOrdinal(100);
> -    }
> -
> -    @Override
> -    public String getName() {
> -        return "TestPropertySource";
> -    }
> -
> -    @Override
> -    public Map<String, String> getProperties() {
> -        return VALUES;
> -    }
> -}
> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
> ----------------------------------------------------------------------
> diff --git 
> a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java 
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
> new file mode 100644
> index 0000000..beafbf9
> --- /dev/null
> +++ 
> b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
> @@ -0,0 +1,32 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements.  See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership.  The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License.  You may obtain a copy of the License at
> + *
> + *  http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied.  See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + */
> +package org.apache.tamaya.core.testdata;
> +
> +import org.apache.tamaya.core.PathBasedPropertySourceProvider;
> +import org.apache.tamaya.core.formats.PropertiesFormat;
> +
> +/**
> + * Test provider reading properties from classpath:cfg/final/**.properties.
> + */
> +public class TestPropertySourceProvider extends 
> PathBasedPropertySourceProvider{
> +
> +    public TestPropertySourceProvider() {
> +        super("final-testdata-properties", new PropertiesFormat(200), 
> "classpath:cfg/final/**/*.properties");
> +    }
> +}
> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
> ----------------------------------------------------------------------
> diff --git 
> a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource 
> b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
> deleted file mode 100644
> index e6f7fad..0000000
> --- 
> a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
> +++ /dev/null
> @@ -1,19 +0,0 @@
> -#
> -# Licensed to the Apache Software Foundation (ASF) under one
> -# or more contributor license agreements.  See the NOTICE file
> -# distributed with this work for additional information
> -# regarding copyright ownership.  The ASF licenses this file
> -# to you under the Apache License, Version 2.0 (the
> -# "License"); you may not use this file except in compliance
> -# with the License.  You may obtain a copy current the License at
> -#
> -#    http://www.apache.org/licenses/LICENSE-2.0
> -#
> -# Unless required by applicable law or agreed to in writing,
> -# software distributed under the License is distributed on an
> -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> -# KIND, either express or implied.  See the License for the
> -# specific language governing permissions and limitations
> -# under the License.
> -#
> -org.apache.tamaya.core.testdata.TestPropertySource
> \ No newline at end of file
> 
> http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
> ----------------------------------------------------------------------
> diff --git 
> a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider 
> b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
> new file mode 100644
> index 0000000..9db0ef4
> --- /dev/null
> +++ 
> b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
> @@ -0,0 +1,20 @@
> +#
> +# Licensed to the Apache Software Foundation (ASF) under one
> +# or more contributor license agreements.  See the NOTICE file
> +# distributed with this work for additional information
> +# regarding copyright ownership.  The ASF licenses this file
> +# to you under the Apache License, Version 2.0 (the
> +# "License"); you may not use this file except in compliance
> +# with the License.  You may obtain a copy current the License at
> +#
> +#    http://www.apache.org/licenses/LICENSE-2.0
> +#
> +# Unless required by applicable law or agreed to in writing,
> +# software distributed under the License is distributed on an
> +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> +# KIND, either express or implied.  See the License for the
> +# specific language governing permissions and limitations
> +# under the License.
> +#
> +org.apache.tamaya.core.testdata.TestPropertyDefaultSourceProvider
> +org.apache.tamaya.core.testdata.TestPropertySourceProvider
> \ No newline at end of file
> 

[2/4] incubator-tamaya git commit: TAMAYA-42, 43, 44: Readded non Spring related parts. Simplified resource API. Readded other tests.

Posted by an...@apache.org.
TAMAYA-42,43,44: Readded non Spring related parts. Simplified resource API. Readded other tests.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/cc237eb4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/cc237eb4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/cc237eb4

Branch: refs/heads/master
Commit: cc237eb41b7d0c660261f451f47bbf07b7770c46
Parents: 59a9e21
Author: anatole <an...@apache.org>
Authored: Sun Jan 4 02:17:56 2015 +0100
Committer: anatole <an...@apache.org>
Committed: Sun Jan 4 02:26:23 2015 +0100

----------------------------------------------------------------------
 .../org/apache/tamaya/spi/PropertyFilter.java   |  10 +-
 .../core/PathBasedPropertySourceProvider.java   |  93 ++++++++++
 .../core/ResourcePropertySourceProvider.java    | 102 +++++++++++
 .../core/formats/ConfigurationFormat.java       |  53 ++++++
 .../tamaya/core/formats/PropertiesFormat.java   | 114 ++++++++++++
 .../core/formats/PropertiesXmlFormat.java       | 115 ++++++++++++
 .../core/internal/DefaultConfiguration.java     |  27 ++-
 .../internal/resource/ClassPathResource.java    | 178 +++++++++++++++++++
 .../resource/DefaultResourceLoader.java         |  93 ++++++++++
 .../core/internal/resource/FileResource.java    | 162 +++++++++++++++++
 .../internal/resource/InputStreamResource.java  | 117 ++++++++++++
 .../core/resources/InputStreamSupplier.java     |  37 ++++
 .../apache/tamaya/core/resources/Resource.java  | 115 ++++++++++++
 .../tamaya/core/resources/ResourceLoader.java   |  91 ++++++++++
 .../apache/tamaya/core/ConfigurationTest.java   |   6 +
 .../EnvironmentPropertySourceTest.java          |  70 --------
 .../TestPropertyDefaultSourceProvider.java      |  32 ++++
 .../core/testdata/TestPropertySource.java       |  55 ------
 .../testdata/TestPropertySourceProvider.java    |  32 ++++
 .../org.apache.tamaya.spi.PropertySource        |  19 --
 ...org.apache.tamaya.spi.PropertySourceProvider |  20 +++
 21 files changed, 1388 insertions(+), 153 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java b/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
index 7479008..c8626fc 100644
--- a/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
+++ b/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
@@ -19,7 +19,7 @@
 package org.apache.tamaya.spi;
 
 
-import java.util.Map;
+import java.util.function.Function;
 
 /**
  * <p>Interface for filtering the current map of properties during the evaluation of the chain of PropertySources.
@@ -27,7 +27,7 @@ import java.util.Map;
  * hereby is defined by the corresponding {@code @Priority} annotation.</p>
  * <p>Filters </p>
  */
-public interface PropertyFilter<T>{
+public interface PropertyFilter{
 
     /**
      * <p>Maps the current {@code valueToBeFiltered} value to a new value. The resulting value will be used as the result
@@ -44,10 +44,10 @@ public interface PropertyFilter<T>{
      *
      * @param key the key accessed, not null.
      * @param valueToBeFiltered the value to be filtered, not null.
-     * @param currentMap the current input property map, not null. Can be used for resolution of the filtered value
-     *                   or as datasource for additional meta-information, such as categories, sensitivity etc.
+     * @param propertyValueProvider accessor for reading additional (eg metadata) properties to perform correct
+     *                              filtering, never null.
      * @return the filtered map, never null.
      */
-    String filterProperty(String key, String valueToBeFiltered, Map<String,String> currentMap);
+    String filterProperty(String key, String valueToBeFiltered, Function<String,String> propertyValueProvider);
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java b/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
new file mode 100644
index 0000000..31dbf4b
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/PathBasedPropertySourceProvider.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core;
+
+import org.apache.tamaya.core.formats.ConfigurationFormat;
+import org.apache.tamaya.core.resources.Resource;
+import org.apache.tamaya.core.resources.ResourceLoader;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertySourceProvider;
+import org.apache.tamaya.spi.ServiceContext;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Implementation of a {@link PropertySourceProvider} that reads configuration from some given resource paths
+ * and using the given formats. The resource path are resolved using the current
+ * {@link org.apache.tamaya.core.resources.ResourceLoader} active.
+ */
+public class PathBasedPropertySourceProvider implements PropertySourceProvider {
+    /** The logger used. */
+    private static final Logger LOG = Logger.getLogger(PathBasedPropertySourceProvider.class.getName());
+    /** The property source base name, will be used for creating a useful name of the
+     * {@link org.apache.tamaya.spi.PropertySource} created. */
+    private String sourceName;
+    /** The config formats supported for the given location/resource paths. */
+    private List<ConfigurationFormat> configFormats = new ArrayList<>();
+    /** The paths to be evaluated. */
+    private List<String> paths = new ArrayList<>();
+
+    /**
+     * Creates a new instance.
+     * @param sourceName the base name of the configuration, used for creating PropertySource child names.
+     * @param formats the formats to be used, not null, not empty.
+     * @param paths the paths to be resolved, not null, not empty.
+     */
+    public PathBasedPropertySourceProvider(String sourceName, List<ConfigurationFormat> formats, String... paths) {
+        this.sourceName = Objects.requireNonNull(sourceName);
+        this.configFormats.addAll(Objects.requireNonNull(formats));
+        this.paths.addAll(Arrays.asList(Objects.requireNonNull(paths)));
+    }
+
+    /**
+     * Creates a new instance.
+     * @param sourceName the base name of the configuration, used for creating PropertySource child names.
+     * @param format the format to be used.
+     * @param paths the paths to be resolved, not null, not empty.
+     */
+    public PathBasedPropertySourceProvider(String sourceName, ConfigurationFormat format, String... paths) {
+        this.sourceName = Objects.requireNonNull(sourceName);
+        this.configFormats.add(Objects.requireNonNull(format));
+        this.paths.addAll(Arrays.asList(Objects.requireNonNull(paths)));
+    }
+
+    @Override
+    public Collection<PropertySource> getPropertySources() {
+        List<PropertySource> propertySources = new ArrayList<>();
+        paths.forEach((path) -> {
+            for (Resource res : ServiceContext.getInstance().getService(ResourceLoader.class).get().getResources(path)) {
+                try {
+                    for (ConfigurationFormat format : configFormats) {
+                        propertySources.addAll(format.readConfiguration(sourceName, res));
+                    }
+                } catch (Exception e) {
+                    LOG.log(Level.WARNING, "Failed to add resource based config: " + res.getName(), e);
+                }
+            }
+        });
+        return propertySources;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java b/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
new file mode 100644
index 0000000..de6b578
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/ResourcePropertySourceProvider.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core;
+
+import org.apache.tamaya.core.formats.ConfigurationFormat;
+import org.apache.tamaya.core.resources.Resource;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertySourceProvider;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+import java.util.logging.Logger;
+
+/**
+ * Implementation of a {@link org.apache.tamaya.spi.PropertySourceProvider} that is based on a single resource
+ * and a number of formats.
+ */
+public class ResourcePropertySourceProvider implements PropertySourceProvider {
+    /** The logger used. */
+    private static final Logger LOG = Logger.getLogger(ResourcePropertySourceProvider.class.getName());
+    /** The supported formats. */
+    private List<ConfigurationFormat> formats = new ArrayList<>();
+    /** The resource. */
+    private Resource resource;
+    /** The source name used for creating the PropertySource names. */
+    private String sourceName;
+
+    /**
+     * Creates a new instance.
+     * @param resource the {@link org.apache.tamaya.core.resources.Resource}, not null.
+     * @param formats the supported formats, not empty.
+     */
+    public ResourcePropertySourceProvider(String sourceName, Resource resource, ConfigurationFormat... formats) {
+        this(sourceName, resource, Arrays.asList(formats));
+    }
+
+    /**
+     * Creates a new instance.
+     * @param resource the {@link org.apache.tamaya.core.resources.Resource}, not null.
+     * @param formats the supported formats, not empty.
+     */
+    public ResourcePropertySourceProvider(String sourceName, Resource resource, List<ConfigurationFormat> formats) {
+        this.resource = Objects.requireNonNull(resource);
+        this.sourceName = Objects.requireNonNull(sourceName);
+        if(formats.size()==0){
+            throw new IllegalArgumentException("Format required.");
+        }
+        this.formats.addAll(formats);
+    }
+
+
+    /**
+     * Get the underlying resource.
+     *
+     * @return the underlying resource, never null.
+     */
+    public Resource getResource() {
+        return this.resource;
+    }
+
+
+    @Override
+    public String toString() {
+        return "ResourcePropertySourceProvider{" +
+                "resource=" + resource +
+                ", formats=+" + formats +
+                '}';
+    }
+
+    @Override
+    public Collection<PropertySource> getPropertySources() {
+        List<PropertySource> propertySources = new ArrayList<>();
+        for (ConfigurationFormat format : formats) {
+            try {
+                propertySources.addAll(format.readConfiguration(sourceName, resource));
+            } catch (Exception e) {
+                LOG.info(() -> "Format was not matching: " + format + " for resource: " + resource.getName());
+            }
+        }
+        return propertySources;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java b/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
new file mode 100644
index 0000000..5d289bb
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/formats/ConfigurationFormat.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.formats;
+
+import org.apache.tamaya.core.resources.Resource;
+import org.apache.tamaya.spi.PropertySource;
+
+import java.io.IOException;
+import java.util.Collection;
+
+/**
+ * Implementations current this class encapsulate the mechanism how to read a
+ * resource including interpreting the format correctly (e.g. xml vs.
+ * properties). In most cases file only contains entries of the same priority, which would then
+ * result in only one {@link PropertySource}. Complex file formats, hoiwever, may contain entries
+ * of different priorities. In this cases, each ordinal type found must be returned as a separate
+ * {@link PropertySource} instance.
+ */
+@FunctionalInterface
+public interface ConfigurationFormat {
+
+    /**
+     * Reads a list {@link org.apache.tamaya.spi.PropertySource} instances from a resource, using this format.
+     * If the configuration format only contains entries of one ordinal type, normally only one single
+     * instance of PropertySource is returned. Nevertheless custom formats may contain different sections or parts,
+     * where each part maps to a different target rdinal (eg defaults, domain config and app config). In the
+     * ladder case multiple PropertySources can be returned, each one with its own ordinal and the corresponding
+     * entries.
+     *
+     * @param sourceName name to be used for constructing a useful name for the created
+     *                   {@link org.apache.tamaya.spi.PropertySource} instances.
+     * @param resource   the configuration resource, not null
+     * @return the corresponding {@link org.apache.tamaya.spi.PropertySource} instances, never {@code null}.
+     */
+    Collection<PropertySource> readConfiguration(String sourceName, Resource resource) throws IOException;
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
new file mode 100644
index 0000000..3584f8e
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesFormat.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.formats;
+
+import org.apache.tamaya.core.resources.Resource;
+import org.apache.tamaya.spi.PropertySource;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Implementation of a {@link org.apache.tamaya.core.formats.ConfigurationFormat} for -properties files.
+ *
+ * @see java.util.Properties#load(java.io.InputStream)
+ */
+public class PropertiesFormat implements ConfigurationFormat {
+    /**
+     * The logger.
+     */
+    private final static Logger LOG = Logger.getLogger(PropertiesFormat.class.getName());
+
+    /**
+     * The target ordinal.
+     */
+    private int ordinal;
+
+    /**
+     * Creates a new format instance, hereby producing entries with the given ordinal, if not overridden by the
+     * configuration itself.
+     * TODO document and implement override feature
+     * @param ordinal the target ordinal.
+     */
+    public PropertiesFormat(int ordinal) {
+        this.ordinal = ordinal;
+    }
+
+    /**
+     * Get the target ordinal, produced by this format.
+     *
+     * @return the target ordinal
+     */
+    public int getOrdinal() {
+        return ordinal;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Collection<PropertySource> readConfiguration(String baseName, Resource resource) {
+        final String sourceName = (baseName==null?"Properties:":baseName) + resource.getName();
+        if (resource.exists()) {
+            List<PropertySource> propertySources = new ArrayList<>();
+            try (InputStream is = resource.getInputStream()) {
+                final Properties p = new Properties();
+                p.load(is);
+                propertySources.add(new PropertySource() {
+                    @Override
+                    public int getOrdinal() {
+                        return ordinal;
+                    }
+
+                    @Override
+                    public String getName() {
+                        return sourceName;
+                    }
+
+                    @Override
+                    public Optional<String> get(String key) {
+                        return Optional.ofNullable(p.getProperty(key));
+                    }
+
+                    @Override
+                    public Map<String, String> getProperties() {
+                        return Map.class.cast(p);
+                    }
+                });
+                return propertySources;
+            } catch (Exception e) {
+                LOG.log(Level.FINEST, e, () -> "Failed to read config from resource: " + resource);
+            }
+        }
+        return Collections.emptyList();
+    }
+
+    @Override
+    public String toString() {
+        return "PropertiesFormat{" +
+                "ordinal=" + ordinal +
+                '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
new file mode 100644
index 0000000..3f77810
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/formats/PropertiesXmlFormat.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.formats;
+
+import org.apache.tamaya.core.resources.Resource;
+import org.apache.tamaya.spi.PropertySource;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Implementation of a {@link org.apache.tamaya.core.formats.ConfigurationFormat} for xml property
+ * files.
+ *
+ * @see java.util.Properties#loadFromXML(java.io.InputStream)
+ */
+public class PropertiesXmlFormat implements ConfigurationFormat {
+    /**
+     * The logger.
+     */
+    private final static Logger LOG = Logger.getLogger(PropertiesXmlFormat.class.getName());
+
+    /**
+     * The target ordinal.
+     */
+    private int ordinal;
+
+    /**
+     * Creates a new format instance, producing entries for the given ordinal, if not overridden by a
+     * config entry itself.
+     * TODO document and implement override feature
+     * @param ordinal the target ordinal.
+     */
+    public PropertiesXmlFormat(int ordinal) {
+        this.ordinal = ordinal;
+    }
+
+    /**
+     * Get the target ordinal, produced by this format.
+     *
+     * @return the target ordinal
+     */
+    public int getOrdinal() {
+        return ordinal;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Collection<PropertySource> readConfiguration(String baseName, Resource resource) {
+        if (resource.exists()) {
+            final String sourceName = (baseName==null?"Properties:":baseName) + resource.getName();
+            List<PropertySource> propertySources = new ArrayList<>();
+            try (InputStream is = resource.getInputStream()) {
+                final Properties p = new Properties();
+                p.loadFromXML(is);
+                propertySources.add(new PropertySource() {
+                    @Override
+                    public int getOrdinal() {
+                        return ordinal;
+                    }
+
+                    @Override
+                    public String getName() {
+                        return sourceName;
+                    }
+
+                    @Override
+                    public Optional<String> get(String key) {
+                        return Optional.ofNullable(p.getProperty(key));
+                    }
+
+                    @Override
+                    public Map<String, String> getProperties() {
+                        return Map.class.cast(p);
+                    }
+                });
+                return propertySources;
+            } catch (Exception e) {
+                LOG.log(Level.FINEST, e, () -> "Failed to read config from resource: " + resource);
+            }
+        }
+        return Collections.emptyList();
+    }
+
+    @Override
+    public String toString() {
+        return "PropertiesXmlFormat{" +
+                "ordinal=" + ordinal +
+                '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java b/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
index 0a39b7d..3769e27 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
@@ -22,6 +22,7 @@ import org.apache.tamaya.ConfigException;
 import org.apache.tamaya.Configuration;
 import org.apache.tamaya.spi.ConfigurationContext;
 import org.apache.tamaya.spi.PropertyConverter;
+import org.apache.tamaya.spi.PropertyFilter;
 import org.apache.tamaya.spi.PropertySource;
 import org.apache.tamaya.spi.ServiceContext;
 
@@ -33,6 +34,7 @@ import java.util.Map;
 import java.util.Optional;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import java.util.stream.Collectors;
 
 /**
  * Implementation of the Configuration API. This class uses the current {@link ConfigurationContext} to evaluate the
@@ -56,13 +58,21 @@ public class DefaultConfiguration implements Configuration {
     @Override
     public Optional<String> get(String key) {
         List<PropertySource> propertySources = ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertySources();
+        String unfilteredValue = null;
         for (PropertySource propertySource : propertySources) {
             Optional<String> value = propertySource.get(key);
             if (value.isPresent()) {
-                return value;
+                unfilteredValue = value.get();
+                break;
             }
         }
-        return Optional.empty();
+        // Apply filters to values, prevent values filtered to null!
+        for(PropertyFilter filter:
+                ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyFilters()){
+            unfilteredValue = filter.filterProperty(key, unfilteredValue,
+                    (String k) -> key.equals(k)?null:get(k).orElse(null));
+        }
+        return Optional.ofNullable(unfilteredValue);
     }
 
     @Override
@@ -83,7 +93,15 @@ public class DefaultConfiguration implements Configuration {
                 LOG.log(Level.SEVERE, "Error adding properties from PropertySource: " + propertySource +", ignoring PropertySource.", e);
             }
         }
-        return result;
+        // Apply filters to values, prevent values filtered to null!
+        for(PropertyFilter filter:
+                ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyFilters()){
+            result.replaceAll((k,v) -> filter.filterProperty(k, v,
+                    (String k2) -> k2.equals(k)?null:get(k2).orElse(null)));
+        }
+        // Remove null values
+        return result.entrySet().parallelStream().filter((e) -> e.getValue()!=null).collect(
+                Collectors.toMap((e) -> e.getKey(), (e) -> e.getValue()));
     }
 
     /**
@@ -101,7 +119,8 @@ public class DefaultConfiguration implements Configuration {
     public <T> Optional<T> get(String key, Class<T> type) {
         Optional<String> value = get(key);
         if (value.isPresent()) {
-            List<PropertyConverter<T>> converters = ServiceContext.getInstance().getService(ConfigurationContext.class).get().getPropertyConverters(type);
+            List<PropertyConverter<T>> converters = ServiceContext.getInstance().getService(ConfigurationContext.class)
+                    .get().getPropertyConverters(type);
             for (PropertyConverter<T> converter : converters) {
                 try {
                     T t = converter.convert(value.get());

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java b/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
new file mode 100644
index 0000000..21806cd
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/resource/ClassPathResource.java
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal.resource;
+
+import org.apache.tamaya.core.resources.Resource;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Objects;
+
+/**
+ * Implementation of {@link Resource} to be loaded from the classpath.
+ */
+public class ClassPathResource implements Resource {
+
+    private final String path;
+
+    private ClassLoader classLoader;
+
+
+    /**
+     * Create a new resource using the current context class loader.
+     *
+     * @param path the resource path, not null
+     * @see java.lang.ClassLoader#getResourceAsStream(String)
+     */
+    public ClassPathResource(String path) {
+        this(path, (ClassLoader) null);
+    }
+
+    /**
+     * Create a new resource using the given class loader.
+     *
+     * @param path        the resource path, not null
+     * @param classLoader the class loader to load the resource with,
+     *                    or {@code null} for the current context class loader
+     * @see ClassLoader#getResourceAsStream(String)
+     */
+    public ClassPathResource(String path, ClassLoader classLoader) {
+        Objects.requireNonNull(path, "Path null");
+        if (path.startsWith("/")) {
+            path = path.substring(1);
+        }
+        this.path = path.trim();
+        if(classLoader==null){
+            classLoader = Thread.currentThread().getContextClassLoader();
+        }
+        if(classLoader==null){
+            classLoader = getClass().getClassLoader();
+        }
+        this.classLoader = classLoader;
+    }
+
+    /**
+     * @return the path for this resource.
+     */
+    public final String getPath() {
+        return this.path;
+    }
+
+    /**
+     * @return the ClassLoader that this resource will be accessed from.
+     */
+    public final ClassLoader getClassLoader() {
+        return this.classLoader;
+    }
+
+
+    /**
+     * Checks if the given resource is resolvable from the configured classloader.
+     *
+     * @see java.lang.ClassLoader#getResource(String)
+     */
+    @Override
+    public boolean exists() {
+        return (resolveURL() != null);
+    }
+
+    /**
+     * Resolves a URL for the underlying class path resource.
+     *
+     * @return the resolved URL, or {@code null}
+     */
+    protected URL resolveURL() {
+        return this.classLoader.getResource(this.path);
+    }
+
+    /**
+     * This implementation opens an InputStream for the given class path resource.
+     *
+     * @see java.lang.ClassLoader#getResourceAsStream(String)
+     * @see java.lang.Class#getResourceAsStream(String)
+     */
+    @Override
+    public InputStream getInputStream() throws IOException {
+        InputStream is = this.classLoader.getResourceAsStream(this.path);
+        if (is == null) {
+            throw new IOException(getName() + " does not exist");
+        }
+        return is;
+    }
+
+    @Override
+    public URI toURI() throws IOException {
+        try {
+            return resolveURL().toURI();
+        } catch (URISyntaxException e) {
+            throw new IOException(e);
+        }
+    }
+
+    @Override
+    public long lastModified() throws IOException {
+        return 0;
+    }
+
+    /**
+     * This implementation returns the name current the file that this class path
+     * resource refers to.
+     */
+    @Override
+    public String getName() {
+        return "classpath:"+path;
+    }
+
+    /**
+     * This implementation returns a description that includes the class path location.
+     */
+    @Override
+    public String toString() {
+        return "ClassPathResource[" + path + ']';
+    }
+
+    /**
+     * This implementation compares the underlying class path locations.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof ClassPathResource) {
+            ClassPathResource otherRes = (ClassPathResource) obj;
+            return (this.path.equals(otherRes.path) &&
+                    Objects.equals(this.classLoader, otherRes.classLoader));
+        }
+        return false;
+    }
+
+    /**
+     * This implementation returns the hash code current the underlying
+     * class path location.
+     */
+    @Override
+    public int hashCode() {
+        return getName().hashCode();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java b/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
new file mode 100644
index 0000000..eb56c1d
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/resource/DefaultResourceLoader.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal.resource;
+
+import org.apache.tamaya.core.resources.Resource;
+import org.apache.tamaya.core.resources.ResourceLoader;
+
+import javax.annotation.Priority;
+import java.io.File;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.logging.Logger;
+
+/**
+ * Simple default implementation of the resource loader, which does only support direct references to files.
+ */
+@Priority(0)
+public class DefaultResourceLoader implements ResourceLoader {
+
+    private static final Logger LOG = Logger.getLogger(DefaultResourceLoader.class.getName());
+
+    @Override
+    public List<Resource> getResources(ClassLoader classLoader, Collection<String> expressions) {
+        List<Resource> resources = new ArrayList<>();
+        for (String expression : expressions) {
+            if (tryClassPath(classLoader, expression, resources) || tryFile(expression, resources) ||
+                    tryURL(expression, resources)) {
+                continue;
+            }
+            LOG.warning("Failed to resolve resource: " + expression);
+        }
+        return resources;
+    }
+
+    private boolean tryClassPath(ClassLoader classLoader, String expression, List<Resource> resources) {
+        try {
+            Enumeration<URL> urls = classLoader.getResources(expression);
+            while (urls.hasMoreElements()) {
+                URL url = urls.nextElement();
+                resources.add(new URLResource(url));
+            }
+            return !resources.isEmpty();
+        } catch (Exception e) {
+            LOG.finest(() -> "Failed to load resource from CP: " + expression);
+        }
+        return false;
+    }
+
+    private boolean tryFile(String expression, List<Resource> resources) {
+        try {
+            File file = new File(expression);
+            if (file.exists()) {
+                resources.add(new FileResource(file));
+                return true;
+            }
+        } catch (Exception e) {
+            LOG.finest(() -> "Failed to load resource from file: " + expression);
+        }
+        return false;
+    }
+
+    private boolean tryURL(String expression, List<Resource> resources) {
+        try {
+            URL url = new URL(expression);
+            resources.add(new URLResource(url));
+            return true;
+        } catch (Exception e) {
+            LOG.finest(() -> "Failed to load resource from file: " + expression);
+        }
+        return false;
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java b/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
new file mode 100644
index 0000000..e0096e5
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/resource/FileResource.java
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal.resource;
+
+import org.apache.tamaya.core.resources.Resource;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.util.Objects;
+
+/**
+ * Implementation of {@link org.apache.tamaya.core.resources.Resource} to be loaded from a file.
+ * @see java.io.File
+ */
+public class FileResource implements Resource {
+
+    private final File file;
+
+    /**
+     * Creates a new instance.
+     *
+     * @param file a File, not null.
+     */
+    public FileResource(File file) {
+        this.file = Objects.requireNonNull(file, "File must not be null");
+    }
+
+    /**
+     * Crreates a new instance.
+     *
+     * @param filePath a file path
+     */
+    public FileResource(String filePath) {
+        Objects.requireNonNull(filePath, "Path must not be null");
+        this.file = new File(filePath);
+    }
+
+
+    /**
+     * Get the file path for this resource.
+     */
+    public final String getPath() {
+        return this.file.getPath();
+    }
+
+
+    /**
+     * This implementation returns whether the underlying file exists.
+     *
+     * @see java.io.File#exists()
+     */
+    @Override
+    public boolean exists() {
+        return this.file.exists();
+    }
+
+    /**
+     * This implementation checks whether the underlying file is marked as readable
+     * (and corresponds to an actual file with content, not to a directory).
+     *
+     * @see java.io.File#canRead()
+     * @see java.io.File#isDirectory()
+     */
+    @Override
+    public boolean isAccessible() {
+        return (this.file.canRead() && !this.file.isDirectory());
+    }
+
+    /**
+     * This implementation opens a FileInputStream for the underlying file.
+     *
+     * @see java.io.FileInputStream
+     */
+    @Override
+    public InputStream getInputStream() throws IOException {
+        return new FileInputStream(this.file);
+    }
+
+    /**
+     * This implementation returns a URI for the underlying file.
+     *
+     * @see java.io.File#toURI()
+     */
+    @Override
+    public URI toURI() throws IOException {
+        return this.file.toURI();
+    }
+
+    /**
+     * Returns the underlying File's length.
+     */
+    @Override
+    public long length() throws IOException {
+        return this.file.length();
+    }
+
+    @Override
+    public long lastModified() throws IOException {
+        return file.lastModified();
+    }
+
+    /**
+     * Returns the name of the current file.
+     *
+     * @see java.io.File#getName()
+     */
+    @Override
+    public String getName() {
+        return this.file.getName();
+    }
+
+    /**
+     * Returns a description that includes the absolute
+     * path of the current file.
+     *
+     * @see java.io.File#getAbsolutePath()
+     */
+    @Override
+    public String toString() {
+        return "File [" + this.file.getAbsolutePath() + "]";
+    }
+
+
+    // implementation current WritableResource
+
+    /**
+     * Compares the underlying Files.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        return (obj == this ||
+                (obj instanceof FileResource && this.file.equals(((FileResource) obj).file)));
+    }
+
+    /**
+     * Returns hash code current the underlying File reference.
+     */
+    @Override
+    public int hashCode() {
+        return this.file.hashCode();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java b/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
new file mode 100644
index 0000000..09510b4
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/resource/InputStreamResource.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal.resource;
+
+import org.apache.tamaya.core.resources.Resource;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.util.Objects;
+
+/**
+ * Simple Resource encapsulating an InputStream.
+ */
+public class InputStreamResource implements Resource {
+
+    /** The InputStream. */
+    private final InputStream inputStream;
+    /** The read flag. */
+    private boolean read = false;
+    /** The name of the resource. */
+    private String name;
+
+
+    /**
+     * Create a new InputStreamResource.
+     *
+     * @param inputStream the InputStream to use
+     */
+    public InputStreamResource(InputStream inputStream) {
+        this(inputStream, "InputStream:");
+    }
+
+    /**
+     * Create a new InputStreamResource.
+     *
+     * @param inputStream the InputStream to use
+     * @param name where the InputStream comes from
+     */
+    public InputStreamResource(InputStream inputStream, String name) {
+        this.inputStream = Objects.requireNonNull(inputStream);
+        this.name = (name != null ? name : "InputStream");
+    }
+
+
+    /**
+     * This implementation always returns {@code true}.
+     */
+    @Override
+    public boolean exists() {
+        return true;
+    }
+
+    @Override
+    public URI toURI() throws IOException {
+        throw new IOException("URI not available.");
+    }
+
+    @Override
+    public long lastModified() throws IOException {
+        throw new IOException("lastModified not available.");
+    }
+
+    /**
+     * Accesses the input stream. Hereby the input stream can only accessed once.
+     */
+    @Override
+    public InputStream getInputStream() throws IOException {
+        if (this.read) {
+            throw new IllegalStateException("InputStream can only be read once!");
+        }
+        this.read = true;
+        return this.inputStream;
+    }
+
+    /**
+     * This implementation returns the passed-in description, if any.
+     */
+    public String toString() {
+        return this.name != null ? this.name : super.toString();
+    }
+
+
+    /**
+     * Compares the underlying InputStream.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        return (obj == this ||
+                (obj instanceof InputStreamResource && ((InputStreamResource) obj).inputStream.equals(this.inputStream)));
+    }
+
+    /**
+     * This implementation returns the hash code current the underlying InputStream.
+     */
+    @Override
+    public int hashCode() {
+        return this.inputStream.hashCode();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java b/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
new file mode 100644
index 0000000..4da6c53
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/resources/InputStreamSupplier.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.resources;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Simple interface for a component that provides data based on an InputStream.
+ */
+@FunctionalInterface
+public interface InputStreamSupplier {
+
+    /**
+     * Access the input stream.
+     * @return the input stream for use.
+     * @throws IOException i the input stream could not be obtained.
+     */
+    InputStream getInputStream() throws IOException;
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/resources/Resource.java b/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
new file mode 100644
index 0000000..31c679d
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/resources/Resource.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.resources;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URL;
+import java.util.Objects;
+
+/**
+ * Interface for an abstract resource. The effective resource implementation can be completely arbitrary.
+ * By default files, classpath resources and URLs are supported, but alternate implementations are possible.
+ *
+ * @see #getInputStream()
+ * @see #toURI()
+ */
+public interface Resource extends InputStreamSupplier {
+
+    /**
+     * Return whether this resource actually exists. Depending on the resource this can delegate to
+     * {@link java.io.File#exists()} or whatever may be appropriate to check accessibility of the resource.
+     */
+    default boolean exists() {
+        // Try to open a file first, if that fails try to open the stream...
+        try {
+            return new File(toURI()).exists();
+        } catch (IOException ex) {
+            // Fallback
+            try {
+                InputStream is = getInputStream();
+                is.close();
+                return true;
+            } catch (Exception e) {
+                // ignore, just return false for non existing
+                return false;
+            }
+        }
+    }
+
+    /**
+     * Checks whether the resource is accessible, meaning {@link #getInputStream()} should return a InputStream for reading the
+     * resource's content.
+     *
+     * @see #getInputStream()
+     */
+    default boolean isAccessible() {
+        return true;
+    }
+
+    /**
+     * Returns the resource as an URI.
+     *
+     * @throws IOException if the resource cannot be resolved as URI.
+     */
+    URI toURI() throws IOException;
+
+    /**
+     * Determines the length for this resource.
+     *
+     * @throws IOException if the resource is not readable.
+     */
+    default long length() throws IOException {
+        try(InputStream is = this.getInputStream();) {
+            Objects.requireNonNull(is, "resource not available");
+            long length = 0;
+            byte[] buf = new byte[256];
+            int bytesRead;
+            while ((bytesRead = is.read(buf)) > 0) {
+                length += bytesRead;
+            }
+            return length;
+        }
+    }
+
+    /**
+     * Determine the last-modified timestamp for a resource, as UTC ms timestamp
+     *
+     * @throws IOException if the resource is not accessible.
+     */
+    default long lastModified() throws IOException{
+        return new File(toURI()).lastModified();
+    }
+
+    /**
+     * Get a name for the resource. The name should be identifying the resource and also
+     * never change, so it must be eligible for hashcode/equals implementations.
+     */
+    default String getName() {
+        try {
+            return toURI().toString();
+        } catch (Exception e) {
+            return toString();
+        }
+    }
+
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java b/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
new file mode 100644
index 0000000..5aff10a
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/resources/ResourceLoader.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.resources;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Interface to be implemented by modules. By default only direct file/resource resolution is supported, whereas
+ * extension modules may add functionality to perform ant styled pattern resolution of resources.
+ */
+public interface ResourceLoader {
+
+    /**
+     * Resolves resource expressions to a list of {@link org.apache.tamaya.core.resources.Resource}s. Hereby
+     * the ordering of resources matches the input of the resolved expressions. Nevertheless be aware that
+     * there is no determined ordering of resources located within a classloader.
+     *
+     * @param expressions the expressions to be resolved, not empty.
+     * @return the corresponding collection of current {@link org.apache.tamaya.core.resources.Resource}s found, never
+     * null.
+     * .
+     */
+    default Collection<Resource> getResources(Collection<String> expressions) {
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        if (cl == null) {
+            cl = getClass().getClassLoader();
+        }
+        return getResources(cl, expressions);
+    }
+
+    /**
+     * Resolves resource expressions to a list of {@link org.apache.tamaya.core.resources.Resource}s. Hereby
+     * the ordering of resources matches the input of the resolved expressions. Nevertheless be aware that
+     * there is no determined ordering of resources located within a classloader.
+     *
+     * @param expressions the expressions to be resolved, not empty.
+     * @return the corresponding collection of current {@link org.apache.tamaya.core.resources.Resource}s found, never
+     * null.
+     * .
+     */
+    default Collection<Resource> getResources(String... expressions) {
+        return getResources(Arrays.asList(expressions));
+    }
+
+    /**
+     * Resolves resource expressions to a list of {@link org.apache.tamaya.core.resources.Resource}s, considerubg
+     * the given classloader for classloader dependent resources. Hereby
+     * the ordering of resources matches the input of the resolved expressions. Nevertheless be aware that
+     * there is no determined ordering of resources located within a classloader.
+     *
+     * @param expressions the expressions to be resolved, not empty.
+     * @return the corresponding collection of current {@link org.apache.tamaya.core.resources.Resource}s found, never
+     * null.
+     * .
+     */
+    default Collection<Resource> getResources(ClassLoader classLoader, String... expressions){
+        return getResources(classLoader, Arrays.asList(expressions));
+    }
+
+    /**
+     * Resolves resource expressions to a list of {@link org.apache.tamaya.core.resources.Resource}s, considerubg
+     * the given classloader for classloader dependent resources. Hereby
+     * the ordering of resources matches the input of the resolved expressions. Nevertheless be aware that
+     * there is no determined ordering of resources located within a classloader.
+     *
+     * @param expressions the expressions to be resolved, not empty.
+     * @return the corresponding collection of current {@link org.apache.tamaya.core.resources.Resource}s found, never
+     * null.
+     * .
+     */
+    Collection<Resource> getResources(ClassLoader classLoader, Collection<String> expressions);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java b/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
index be1eadb..9c7b894 100644
--- a/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
+++ b/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
@@ -41,6 +41,12 @@ public class ConfigurationTest {
         assertEquals("Lukas", Configuration.current().get("name3").get());  // oderridden default
         assertEquals("Sereina", Configuration.current().get("name4").get()); // final only
         assertEquals("Benjamin", Configuration.current().get("name5").get()); // final only
+
+        System.out.println("name : " + Configuration.current().get("name").get());
+        System.out.println("name2: " + Configuration.current().get("name2").get());
+        System.out.println("name3: " + Configuration.current().get("name3").get());
+        System.out.println("name4: " + Configuration.current().get("name4").get());
+        System.out.println("name5: " + Configuration.current().get("name5").get());
     }
 
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java b/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
deleted file mode 100644
index 51cc2dc..0000000
--- a/core/src/test/java/org/apache/tamaya/core/test/propertysource/EnvironmentPropertySourceTest.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tamaya.core.test.propertysource;
-
-import org.apache.tamaya.core.propertysource.DefaultOrdinal;
-import org.apache.tamaya.core.propertysource.EnvironmentPropertySource;
-import org.junit.Assert;
-import org.junit.Test;
-
-import java.util.Map;
-import java.util.Optional;
-
-public class EnvironmentPropertySourceTest {
-
-    private EnvironmentPropertySource propertySource = new EnvironmentPropertySource();
-
-
-    @Test
-    public void testGetOrdinal() {
-        Assert.assertEquals(DefaultOrdinal.ENVIRONMENT_PROPERTIES, propertySource.getOrdinal());
-    }
-
-    @Test
-    public void testGet() {
-        String environmentPropertyToCheck = System.getenv().keySet().iterator().next();
-
-        Optional<String> value = propertySource.get(environmentPropertyToCheck);
-        Assert.assertTrue(value.isPresent());
-        Assert.assertEquals(System.getenv(environmentPropertyToCheck), value.get());
-    }
-
-    @Test
-    public void testGetProperties() {
-        Map<String, String> environmentProperties = System.getenv();
-
-        Assert.assertEquals(environmentProperties.size(), propertySource.getProperties().size());
-
-        for (Map.Entry<String, String> propertySourceEntry : propertySource.getProperties().entrySet()) {
-            Assert.assertEquals("Entry values for key '" + propertySourceEntry.getKey() + "' do not match",
-                                environmentProperties.get(propertySourceEntry.getKey()), propertySourceEntry.getValue());
-        }
-
-        // modification is not allowed
-        try {
-            propertySource.getProperties().put("add.new.keys", "must throw exception");
-            Assert.fail(UnsupportedOperationException.class.getName() + " expected");
-        }
-        catch (UnsupportedOperationException e) {
-            // expected -> all is fine
-        }
-    }
-
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
new file mode 100644
index 0000000..5fa90b1
--- /dev/null
+++ b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.testdata;
+
+import org.apache.tamaya.core.PathBasedPropertySourceProvider;
+import org.apache.tamaya.core.formats.PropertiesFormat;
+
+/**
+ * Test provider reading properties from classpath:cfg/defaults/**.properties.
+ */
+public class TestPropertyDefaultSourceProvider extends PathBasedPropertySourceProvider{
+
+    public TestPropertyDefaultSourceProvider() {
+        super("default-testdata-properties", new PropertiesFormat(100), "classpath:cfg/defaults/**/*.properties");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
deleted file mode 100644
index d1314aa..0000000
--- a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySource.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tamaya.core.testdata;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.tamaya.core.propertysource.BasePropertySource;
-
-/**
- * Test provider reading properties from classpath:cfg/final/**.properties.
- */
-public class TestPropertySource extends BasePropertySource {
-
-    private static final Map<String, String> VALUES;
-    static {
-        VALUES = new HashMap<String, String>();
-        VALUES.put("name", "Robin");
-        VALUES.put("name2", "Sabine");
-        VALUES.put("name3", "Lukas");
-        VALUES.put("name4", "Sereina");
-        VALUES.put("name5", "Benjamin");
-    }
-
-
-    public TestPropertySource() {
-        initialzeOrdinal(100);
-    }
-
-    @Override
-    public String getName() {
-        return "TestPropertySource";
-    }
-
-    @Override
-    public Map<String, String> getProperties() {
-        return VALUES;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
new file mode 100644
index 0000000..beafbf9
--- /dev/null
+++ b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.testdata;
+
+import org.apache.tamaya.core.PathBasedPropertySourceProvider;
+import org.apache.tamaya.core.formats.PropertiesFormat;
+
+/**
+ * Test provider reading properties from classpath:cfg/final/**.properties.
+ */
+public class TestPropertySourceProvider extends PathBasedPropertySourceProvider{
+
+    public TestPropertySourceProvider() {
+        super("final-testdata-properties", new PropertiesFormat(200), "classpath:cfg/final/**/*.properties");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
----------------------------------------------------------------------
diff --git a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
deleted file mode 100644
index e6f7fad..0000000
--- a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy current the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-org.apache.tamaya.core.testdata.TestPropertySource
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cc237eb4/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
----------------------------------------------------------------------
diff --git a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
new file mode 100644
index 0000000..9db0ef4
--- /dev/null
+++ b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
@@ -0,0 +1,20 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy current the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+org.apache.tamaya.core.testdata.TestPropertyDefaultSourceProvider
+org.apache.tamaya.core.testdata.TestPropertySourceProvider
\ No newline at end of file


[3/4] incubator-tamaya git commit: CHanged interface to non instantiatable class (effective Java recommendation).

Posted by an...@apache.org.
CHanged interface to non instantiatable class (effective Java recommendation).


Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/3b29a32c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/3b29a32c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/3b29a32c

Branch: refs/heads/master
Commit: 3b29a32cd15decc55758d4c766074b9679de47b0
Parents: 66759b5
Author: anatole <an...@apache.org>
Authored: Sun Jan 4 02:24:39 2015 +0100
Committer: anatole <an...@apache.org>
Committed: Sun Jan 4 02:26:24 2015 +0100

----------------------------------------------------------------------
 .../tamaya/core/propertysource/DefaultOrdinal.java       | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/3b29a32c/core/src/main/java/org/apache/tamaya/core/propertysource/DefaultOrdinal.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/propertysource/DefaultOrdinal.java b/core/src/main/java/org/apache/tamaya/core/propertysource/DefaultOrdinal.java
index 43b3fad..38ec905 100644
--- a/core/src/main/java/org/apache/tamaya/core/propertysource/DefaultOrdinal.java
+++ b/core/src/main/java/org/apache/tamaya/core/propertysource/DefaultOrdinal.java
@@ -25,22 +25,25 @@ package org.apache.tamaya.core.propertysource;
  *
  * DefaultOrdinals can be overwritten via {@link org.apache.tamaya.spi.PropertySource#TAMAYA_ORDINAL}
  */
-public interface DefaultOrdinal {
+public final class DefaultOrdinal {
+
+    /** Private constructor. */
+    private DefaultOrdinal(){}
 
     /**
      * default ordinal for {@link org.apache.tamaya.core.propertysource.BasePropertySource} if
      * not overriden in each class
      */
-    static final int PROPERTY_SOURCE = 1000;
+    public static final int PROPERTY_SOURCE = 1000;
 
     /**
      * default ordinal for {@link org.apache.tamaya.core.propertysource.SystemPropertySource}
      */
-    static final int SYSTEM_PROPERTIES = 400;
+    public static final int SYSTEM_PROPERTIES = 400;
 
     /**
      * default ordinal for {@link org.apache.tamaya.core.propertysource.EnvironmentPropertySource}
      */
-    static final int ENVIRONMENT_PROPERTIES = 300;
+    public static final int ENVIRONMENT_PROPERTIES = 300;
 
 }


[4/4] incubator-tamaya git commit: TAMAYA-42, 43, 44: Readded test code and service configs.

Posted by an...@apache.org.
TAMAYA-42,43,44: Readded test code and service configs.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/7272198b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/7272198b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/7272198b

Branch: refs/heads/master
Commit: 7272198b6f863e83092364589e6373193e0f2335
Parents: 3b29a32
Author: anatole <an...@apache.org>
Authored: Sun Jan 4 02:50:35 2015 +0100
Committer: anatole <an...@apache.org>
Committed: Sun Jan 4 02:50:35 2015 +0100

----------------------------------------------------------------------
 ...g.apache.tamaya.core.resources.ResourceLoader | 19 +++++++++++++++++++
 .../TestPropertyDefaultSourceProvider.java       |  2 +-
 .../testdata/TestPropertySourceProvider.java     |  2 +-
 3 files changed, 21 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7272198b/core/src/main/resources/META-INF/services/org.apache.tamaya.core.resources.ResourceLoader
----------------------------------------------------------------------
diff --git a/core/src/main/resources/META-INF/services/org.apache.tamaya.core.resources.ResourceLoader b/core/src/main/resources/META-INF/services/org.apache.tamaya.core.resources.ResourceLoader
new file mode 100644
index 0000000..d3242e4
--- /dev/null
+++ b/core/src/main/resources/META-INF/services/org.apache.tamaya.core.resources.ResourceLoader
@@ -0,0 +1,19 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy current the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+org.apache.tamaya.core.internal.resource.DefaultResourceLoader

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7272198b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
index 5fa90b1..dffe67d 100644
--- a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
+++ b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSourceProvider.java
@@ -27,6 +27,6 @@ import org.apache.tamaya.core.formats.PropertiesFormat;
 public class TestPropertyDefaultSourceProvider extends PathBasedPropertySourceProvider{
 
     public TestPropertyDefaultSourceProvider() {
-        super("default-testdata-properties", new PropertiesFormat(100), "classpath:cfg/defaults/**/*.properties");
+        super("default-testdata-properties", new PropertiesFormat(100), "cfg/defaults/test1.properties");
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7272198b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
index beafbf9..718aaae 100644
--- a/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
+++ b/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
@@ -27,6 +27,6 @@ import org.apache.tamaya.core.formats.PropertiesFormat;
 public class TestPropertySourceProvider extends PathBasedPropertySourceProvider{
 
     public TestPropertySourceProvider() {
-        super("final-testdata-properties", new PropertiesFormat(200), "classpath:cfg/final/**/*.properties");
+        super("final-testdata-properties", new PropertiesFormat(200), "cfg/final/anotherTestFile.properties");
     }
 }