TAMAYA-145: Simplified syntax and MetaContext. Added tests.

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

Branch: refs/heads/master
Commit: 10d711e6a7e15996c54baad0edf0b38102d3afa7
Parents: 098c75f
Author: anatole <anat...@apache.org>
Authored: Tue Apr 18 00:14:42 2017 +0200
Committer: anatole <anat...@apache.org>
Committed: Tue Apr 18 00:14:42 2017 +0200

----------------------------------------------------------------------
 .../apache/tamaya/metamodel/CachedFilter.java   | 108 +++++++++++
 .../org/apache/tamaya/metamodel/HideFilter.java |  67 +++++++
 .../tamaya/metamodel/ImmutableFilter.java       |  55 ++++++
 .../org/apache/tamaya/metamodel/MapFilter.java  | 101 ++++++++++
 .../org/apache/tamaya/metamodel/MaskFilter.java | 121 ++++++++++++
 .../apache/tamaya/metamodel/MetaContext.java    | 112 +++--------
 .../apache/tamaya/metamodel/SecuredFilter.java  | 119 ++++++++++++
 .../metamodel/ext/FilteredPropertySource.java   |  25 ++-
 .../internal/CombinationPolicyReader.java       |   2 +-
 .../internal/ComponentConfigurator.java         |  19 +-
 .../metamodel/internal/ContextReader.java       | 181 ------------------
 .../metamodel/internal/MetaContextReader.java   | 185 +++++++++++++++++++
 .../internal/PropertyConverterReader.java       |  55 +++---
 .../internal/PropertyFilterReader.java          |  47 +++--
 .../internal/PropertySourceReader.java          | 132 +++++++------
 .../factories/FilePropertySourceFactory.java    |  10 +-
 .../ResourcePropertySourceFactory.java          |   8 +-
 .../ResourcePropertySourceProviderFactory.java  |   8 +-
 .../factories/URLPropertySourceFactory.java     |   6 +-
 .../internal/resolver/PropertiesResolver.java   |  13 +-
 .../org.apache.tamaya.metamodel.spi.ItemFactory |   7 +
 ...tamaya.metamodel.spi.MetaConfigurationReader |   2 +-
 .../tamaya/metamodel/ext/IntegrationTest.java   | 107 ++++++++++-
 .../tamaya/metamodel/ext/MyConverter.java       |  33 ++++
 .../apache/tamaya/metamodel/ext/MyFilter.java   |  33 ++++
 .../tamaya/metamodel/ext/MyPropertySource.java  |  35 ++++
 .../resources/IntegrationTests/context-test.xml |  29 +++
 .../default-propertyconverters-test.xml         |  31 ++++
 .../default-propertyfilters-test.xml            |  26 +++
 .../default-propertysources-test.xml            |  29 +++
 .../propertyconverters-test.xml                 |  30 +++
 .../IntegrationTests/propertyfilters-test.xml   |  26 +++
 .../IntegrationTests/propertysources-test.xml   |  25 +++
 .../org.apache.tamaya.spi.PropertyFilter        |  19 ++
 metamodel/src/test/resources/tamaya-config.xml  |  96 ++++------
 35 files changed, 1419 insertions(+), 483 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/CachedFilter.java
----------------------------------------------------------------------
diff --git 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/CachedFilter.java 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/CachedFilter.java
new file mode 100644
index 0000000..c07e11d
--- /dev/null
+++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/CachedFilter.java
@@ -0,0 +1,108 @@
+package org.apache.tamaya.metamodel;/*
+ * (C) Copyright 2015-2017 Trivadis AG. All rights reserved.
+ */
+
+import org.apache.tamaya.metamodel.spi.ItemFactory;
+import org.apache.tamaya.spi.FilterContext;
+import org.apache.tamaya.spi.PropertyFilter;
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Simple filter that never changes a key/value pair returned, regardless if a 
value
+ * is changing underneath, hereby different values for single and 
multi-property access
+ * are considered.
+ */
+public class CachedFilter implements PropertyFilter{
+
+    private String matches;
+    private Map<String, CachedEntry> cachedEntries = new ConcurrentHashMap<>();
+    private int maxSize = -1;
+    private long timeout = TimeUnit.MINUTES.toMillis(5);
+
+    /**
+     * Factory for configuring immutable property filter.
+     */
+    public static final class CachedFilterFactory implements 
ItemFactory<PropertyFilter> {
+        @Override
+        public String getName() {
+            return "Cached";
+        }
+
+        @Override
+        public PropertyFilter create(Map<String,String> parameters) {
+            return new CachedFilter();
+        }
+
+        @Override
+        public Class<? extends PropertyFilter> getType() {
+            return PropertyFilter.class;
+        }
+    }
+
+    public String getMatches() {
+        return matches;
+    }
+
+    public CachedFilter setMatches(String matches) {
+        this.matches = matches;
+        return this;
+    }
+
+    @Override
+    public PropertyValue filterProperty(PropertyValue value, FilterContext 
context) {
+        if(matches !=null){
+            if(value.getKey().matches(matches)){
+                return resolveCachedEntry(value);
+            }
+        }
+        return value;
+    }
+
+    /**
+     * Method checks for a cached value. if present and valid the cached value 
is returned.
+     * If not valid the cached entry is removed/updated.
+     * @param value
+     * @return
+     */
+    private PropertyValue resolveCachedEntry(PropertyValue value) {
+        if(maxSize>0 && maxSize<=this.cachedEntries.size()){
+            return value;
+        }
+        CachedEntry ce = cachedEntries.get(value.getKey());
+        if(ce==null || !ce.isValid()){
+            if(value!=null) {
+                ce = new CachedEntry(value, System.currentTimeMillis() + 
timeout);
+                this.cachedEntries.put(value.getKey(), ce);
+            }
+        }
+        return value;
+    }
+
+    @Override
+    public String toString() {
+        return "CachedFilter{" +
+                "matches='" + matches + '\'' +
+                ", cache-size=" + cachedEntries.size() +
+                ", max-size=" + maxSize +
+                ", timeout=" + timeout +
+                '}';
+    }
+
+    private static final class CachedEntry{
+        long ttl;
+        PropertyValue value;
+
+        public CachedEntry (PropertyValue value, long ttl){
+            this.ttl = ttl;
+            this.value = value;
+        }
+
+        public boolean isValid(){
+            return System.currentTimeMillis() > ttl;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/HideFilter.java
----------------------------------------------------------------------
diff --git 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/HideFilter.java 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/HideFilter.java
new file mode 100644
index 0000000..2bd701c
--- /dev/null
+++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/HideFilter.java
@@ -0,0 +1,67 @@
+package org.apache.tamaya.metamodel;/*
+ * (C) Copyright 2015-2017 Trivadis AG. All rights reserved.
+ */
+
+import org.apache.tamaya.metamodel.spi.ItemFactory;
+import org.apache.tamaya.spi.FilterContext;
+import org.apache.tamaya.spi.PropertyFilter;
+import org.apache.tamaya.spi.PropertyValue;
+import org.apache.tamaya.spi.PropertyValueBuilder;
+
+import java.util.Map;
+
+/**
+ * Simple filter that never changes a key/value pair returned, regardless if a 
value
+ * is changing underneath, hereby different values for single and 
multi-property access
+ * are considered.
+ */
+public class HideFilter implements PropertyFilter{
+
+    private String matches;
+
+    /**
+     * Factory for configuring immutable property filter.
+     */
+    public static final class HideFilterFactory implements 
ItemFactory<PropertyFilter> {
+        @Override
+        public String getName() {
+            return "Hide";
+        }
+
+        @Override
+        public PropertyFilter create(Map<String,String> parameters) {
+            return new HideFilter();
+        }
+
+        @Override
+        public Class<? extends PropertyFilter> getType() {
+            return PropertyFilter.class;
+        }
+    }
+
+    public String getMatches() {
+        return matches;
+    }
+
+    public HideFilter setMatches(String matches) {
+        this.matches = matches;
+        return this;
+    }
+
+    @Override
+    public PropertyValue filterProperty(PropertyValue value, FilterContext 
context) {
+        if(matches !=null){
+            if(value.getKey().matches(matches)){
+                return null;
+            }
+        }
+        return value;
+    }
+
+    @Override
+    public String toString() {
+        return "HideFilter{" +
+                "matches='" + matches + '\'' +
+                '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/ImmutableFilter.java
----------------------------------------------------------------------
diff --git 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/ImmutableFilter.java 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/ImmutableFilter.java
new file mode 100644
index 0000000..90c65f5
--- /dev/null
+++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/ImmutableFilter.java
@@ -0,0 +1,55 @@
+package org.apache.tamaya.metamodel;/*
+ * (C) Copyright 2015-2017 Trivadis AG. All rights reserved.
+ */
+
+import org.apache.tamaya.metamodel.spi.ItemFactory;
+import org.apache.tamaya.spi.FilterContext;
+import org.apache.tamaya.spi.PropertyFilter;
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Simple filter that never changes a key/value pair returned, regardless if a 
value
+ * is changing underneath, hereby different values for single and 
multi-property access
+ * are considered.
+ */
+public class ImmutableFilter implements PropertyFilter{
+
+    /**
+     * Factory for configuring immutable property filter.
+     */
+    public static final class ImmutableFilterFactory implements 
ItemFactory<PropertyFilter> {
+        @Override
+        public String getName() {
+            return "Immutable";
+        }
+
+        @Override
+        public PropertyFilter create(Map<String,String> parameters) {
+            return new ImmutableFilter();
+        }
+
+        @Override
+        public Class<? extends PropertyFilter> getType() {
+            return PropertyFilter.class;
+        }
+    }
+
+    private Map<String,PropertyValue> map = new ConcurrentHashMap<>();
+
+    @Override
+    public PropertyValue filterProperty(PropertyValue value, FilterContext 
context) {
+        String key = value.getKey();
+        if(!context.isSinglePropertyScoped()) {
+            key = value.getKey() + "_all";
+        }
+        PropertyValue val = map.get(key);
+        if(val==null){
+            map.put(key, value);
+            val = value;
+        }
+        return val;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/MapFilter.java
----------------------------------------------------------------------
diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/MapFilter.java 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/MapFilter.java
new file mode 100644
index 0000000..ab521dd
--- /dev/null
+++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/MapFilter.java
@@ -0,0 +1,101 @@
+package org.apache.tamaya.metamodel;/*
+ * (C) Copyright 2015-2017 Trivadis AG. All rights reserved.
+ */
+
+import org.apache.tamaya.metamodel.spi.ItemFactory;
+import org.apache.tamaya.spi.FilterContext;
+import org.apache.tamaya.spi.PropertyFilter;
+import org.apache.tamaya.spi.PropertyValue;
+import org.apache.tamaya.spi.PropertyValueBuilder;
+
+import java.util.Map;
+
+/**
+ * Simple filter that never changes a key/value pair returned, regardless if a 
value
+ * is changing underneath, hereby different values for single and 
multi-property access
+ * are considered.
+ */
+public class MapFilter implements PropertyFilter{
+
+    private String target;
+    private String cutoff;
+    private String matches;
+
+    /**
+     * Factory for configuring immutable property filter.
+     */
+    public static final class MapFilterFactory implements 
ItemFactory<PropertyFilter> {
+        @Override
+        public String getName() {
+            return "Map";
+        }
+
+        @Override
+        public PropertyFilter create(Map<String,String> parameters) {
+            return new MapFilter();
+        }
+
+        @Override
+        public Class<? extends PropertyFilter> getType() {
+            return PropertyFilter.class;
+        }
+    }
+
+    public String getTarget() {
+        return target;
+    }
+
+    public MapFilter setTarget(String target) {
+        this.target = target;
+        return this;
+    }
+
+    public String getCutoff() {
+        return cutoff;
+    }
+
+    public MapFilter setCutoff(String cutoff) {
+        this.cutoff = cutoff;
+        return this;
+    }
+
+    public String getMatches() {
+        return matches;
+    }
+
+    public MapFilter setMatches(String matches) {
+        this.matches = matches;
+        return this;
+    }
+
+    @Override
+    public PropertyValue filterProperty(PropertyValue value, FilterContext 
context) {
+        PropertyValueBuilder b = value.toBuilder();
+        String key = value.getKey();
+        if(matches !=null){
+            if(!value.getKey().matches(matches)){
+                return value;
+            }
+        }
+        if(cutoff !=null){
+            if(value.getKey().startsWith(cutoff)){
+                key = key.substring(cutoff.length());
+                b.setKey(key);
+            }
+        }
+        if(target!=null){
+            key = target+key;
+            b.setKey(key);
+        }
+        return b.build();
+    }
+
+    @Override
+    public String toString() {
+        return "MapFilter{" +
+                "target='" + target + '\'' +
+                ", cutoff='" + cutoff + '\'' +
+                ", matches='" + matches + '\'' +
+                '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/MaskFilter.java
----------------------------------------------------------------------
diff --git 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/MaskFilter.java 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/MaskFilter.java
new file mode 100644
index 0000000..d374dc4
--- /dev/null
+++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/MaskFilter.java
@@ -0,0 +1,121 @@
+package org.apache.tamaya.metamodel;/*
+ * (C) Copyright 2015-2017 Trivadis AG. All rights reserved.
+ */
+
+import org.apache.tamaya.metamodel.spi.ItemFactory;
+import org.apache.tamaya.spi.FilterContext;
+import org.apache.tamaya.spi.PropertyFilter;
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Simple filter that never changes a key/value pair returned, regardless if a 
value
+ * is changing underneath, hereby different values for single and 
multi-property access
+ * are considered.
+ */
+public class MaskFilter implements PropertyFilter{
+
+    private String matches;
+    private List<String> roles = new ArrayList<>();
+    private String mask = "*****";
+    private TargetPolicy policy = TargetPolicy.ALL;
+
+    /**
+     * Factory for configuring immutable property filter.
+     */
+    public static final class MaskFilterFactory implements 
ItemFactory<PropertyFilter> {
+        @Override
+        public String getName() {
+            return "Mask";
+        }
+
+        @Override
+        public PropertyFilter create(Map<String,String> parameters) {
+            return new MaskFilter();
+        }
+
+        @Override
+        public Class<? extends PropertyFilter> getType() {
+            return PropertyFilter.class;
+        }
+    }
+
+    public String getMatches() {
+        return matches;
+    }
+
+    public MaskFilter setMatches(String matches) {
+        this.matches = matches;
+        return this;
+    }
+
+    public List<String> getRoles() {
+        return roles;
+    }
+
+    public MaskFilter setRoles(List<String> roles) {
+        this.roles.clear();
+        for(String role:roles) {
+            this.roles.add(role.trim());
+        }
+        return this;
+    }
+
+    public MaskFilter setRoles(String... roles) {
+        return setRoles(Arrays.asList(roles));
+    }
+
+    public MaskFilter setRoles(String roles){
+        setRoles(roles.split(","));
+        return this;
+    }
+
+    public String getMask() {
+        return mask;
+    }
+
+    public MaskFilter setMask(String mask) {
+        this.mask = mask;
+        return this;
+    }
+
+    public TargetPolicy getPolicy() {
+        return policy;
+    }
+
+    public MaskFilter setPolicy(TargetPolicy policy) {
+        this.policy = policy;
+        return this;
+    }
+
+    public MaskFilter setPolicy(String policy) {
+        return setPolicy(TargetPolicy.valueOf(policy));
+    }
+
+    @Override
+    public PropertyValue filterProperty(PropertyValue value, FilterContext 
context) {
+        if(matches !=null){
+            if(value.getKey().matches(matches)){
+                return null;
+            }
+        }
+        return value;
+    }
+
+    @Override
+    public String toString() {
+        return "HideFilter{" +
+                "matches='" + matches + '\'' +
+                '}';
+    }
+
+    private enum TargetPolicy {
+        ALL,
+        SINGLEVALUE,
+        MULTIVALUE
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/MetaContext.java
----------------------------------------------------------------------
diff --git 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/MetaContext.java 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/MetaContext.java
index 1952d8e..9082fc3 100644
--- a/metamodel/src/main/java/org/apache/tamaya/metamodel/MetaContext.java
+++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/MetaContext.java
@@ -18,31 +18,22 @@
  */
 package org.apache.tamaya.metamodel;
 
-import org.apache.tamaya.functions.Supplier;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-import java.util.WeakHashMap;
+import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.TimeUnit;
 
 /**
- * Class managing the configuration system's shared context. This
+ * Class managing a configuration system's meta-context. This
  * context is used by the configuration system to evaluate the
  * right properties, e.g. by defining the current stage or labels
- * that apply to the current configuration. Hereby context are
+ * that apply to the current configuration. Hereby contexts are
  * <ul>
- *     <li>identified by unique names</li>
- *     <li>stackable into a context hierarchy, see {@link 
#combineWith(MetaContext...)}</li>
- *     <li>optionally be valid only in some contexts or for a limited time, 
see {@link #isValid()},
- *     {@link #getInstance(String, Supplier)}</li>
+ *     <li>stackable into a context hierarchy, see {@link 
#combineWith(MetaContext, MetaContext...)}</li>
  *     <li>providing key/values only valid for a certain time (assigned a 
TTL), see {@link #setProperty(String, String, int, TimeUnit)},
  *     {@link #setProperties(Map, long, TimeUnit)}</li>
  * </ul>
- * Additionally there is special support for thread related contexts, see 
{@link #getThreadInstance(boolean)}.
- * Finally there is also one special globally shared context instance, see 
{@link #getCurrentInstance(boolean)}.
+ * Additionally there is special support for thread related contexts, see 
{@link #getThreadInstance()}.
+ * Finally there is also one special globally shared context instance, see 
{@link #getInstance()}.
  */
 public final class MetaContext {
 
@@ -52,54 +43,32 @@ public final class MetaContext {
             return new MetaContext();
         }
     };
-    public static final String DEFAULT_CONTEXT_NAME = "<DEFAULT>";
-
-    private String id;
-
-    private Supplier<Boolean> validSupplier;
 
     private final Map<String,Value> properties = new ConcurrentHashMap<>();
 
-    private static final Map<String,MetaContext> CONTEXTS = new 
WeakHashMap<>();
+    private static final MetaContext globalContext = new MetaContext();
 
-    /**
-     * Access a context by name. Contexts are managed as weak references in 
this class. If no
-     * such context exists, a new instance is created.
-     * @param contextName the context name, not null.
-     * @return the context instance, never null.
-     */
-    public static MetaContext getInstance(String contextName) {
-        return getInstance(contextName, null);
+    /** The unique id of this context. */
+    private MetaContext(){
+        setProperty("_id", UUID.randomUUID().toString());
     }
 
     /**
-     * Access the default context. Contexts are managed as weak references in 
this class. If no
-     * such context exists, a new instance is created.
-     * @return the context instance, never null.
+     * Get the context's id.
+     * @return
      */
-    public static MetaContext getDefaultInstance(){
-        return getInstance(DEFAULT_CONTEXT_NAME);
+    public String getId() {
+        return getProperty("_id", "N/A");
     }
 
+
     /**
-     * Access a context by name. Contexts are managed as weak references in 
this class. If no
-     * such valid context exists, a new instance is created, using the given 
{@code validSupplier}.
-     * @param contextName the context name, not null.
+     * Access the global context. There might be other contexts used in the 
system, which also
+     * may delegate to the global context.
      * @return the context instance, never null.
      */
-    public static MetaContext getInstance(String contextName, 
Supplier<Boolean> validSupplier){
-        synchronized(CONTEXTS){
-            MetaContext ctx = CONTEXTS.get(contextName);
-            if(ctx!=null && ctx.isValid()){
-                return ctx;
-            }
-            ctx = new MetaContext();
-            ctx.id = Objects.requireNonNull(contextName);
-            ctx.validSupplier = validSupplier;
-            CONTEXTS.put(contextName, ctx);
-            return ctx;
-        }
-
+    public static MetaContext getInstance(){
+        return globalContext;
     }
 
     /**
@@ -109,7 +78,7 @@ public final class MetaContext {
      * @return the corresponding context, never null.
      */
     public static MetaContext getThreadInstance(boolean reinit){
-        MetaContext threadContext =THREAD_CONTEXT.get();
+        MetaContext threadContext = THREAD_CONTEXT.get();
         if(reinit){
             threadContext.properties.clear();
         }
@@ -121,44 +90,21 @@ public final class MetaContext {
      * context (overriding).
      * @return the corresponding context, never null.
      */
-    public MetaContext getCurrentInstance(){
-        return getCurrentInstance(false);
+    public MetaContext getThreadInstance(){
+        return getThreadInstance(false);
     }
 
-    /**
-     * Access the current context, which actually is the current context, 
combined with the thread based
-     * context (overriding).
-     * @param reinit if true, clear's the thread's meta context.
-     * @return the corresponding context, never null.
-     */
-    public MetaContext getCurrentInstance(boolean reinit){
-        return this.combineWith(getThreadInstance(reinit));
-    }
 
     /**
-     * Method to evaluate if a context is valid. This basically depends on the
-     * {@code validSupplier}, if any is set. If no supplier is present the 
context is valid.
-     *
-     * @return true, if this context is valid.
-     */
-    public boolean isValid(){
-        return this.validSupplier == null || validSupplier.get();
-    }
-
-
-    /**
-     * Combine this context with the other contexts given, hereby only 
contexts are included
-     * which are {@code valid}, see {@link #isValid()}.
+     * Combine this context with the other contexts given.
      * @param contexts the context to merge with this context.
      * @return the newly created Context.
      */
-    public MetaContext combineWith(MetaContext... contexts) {
+    public static MetaContext combineWith(MetaContext baseContext, 
MetaContext... contexts) {
         MetaContext newContext = new MetaContext();
-        newContext.properties.putAll(this.properties);
+        newContext.properties.putAll(baseContext.properties);
         for(MetaContext ctx:contexts) {
-            if(ctx.isValid()) {
-                newContext.properties.putAll(ctx.properties);
-            }
+            newContext.properties.putAll(ctx.properties);
         }
         return newContext;
     }
@@ -311,8 +257,10 @@ public final class MetaContext {
 
     @Override
     public String toString() {
-        return "Context{" +
-                properties +
+        return "MetaContext{" +
+                "id=" + getId() +
+                ", properties=" + properties +
+                ", global=" + (this == MetaContext.globalContext) +
                 '}';
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/SecuredFilter.java
----------------------------------------------------------------------
diff --git 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/SecuredFilter.java 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/SecuredFilter.java
new file mode 100644
index 0000000..5878106
--- /dev/null
+++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/SecuredFilter.java
@@ -0,0 +1,119 @@
+package org.apache.tamaya.metamodel;/*
+ * (C) Copyright 2015-2017 Trivadis AG. All rights reserved.
+ */
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.metamodel.spi.ItemFactory;
+import org.apache.tamaya.spi.FilterContext;
+import org.apache.tamaya.spi.PropertyFilter;
+import org.apache.tamaya.spi.PropertyValue;
+
+import javax.security.auth.Subject;
+import java.security.*;
+import java.util.Map;
+import java.util.logging.Logger;
+
+/**
+ * Simple filter that never changes a key/value pair returned, regardless if a 
value
+ * is changing underneath, hereby different values for single and 
multi-property access
+ * are considered.
+ */
+public class SecuredFilter implements PropertyFilter{
+
+    private static final Logger LOG = 
Logger.getLogger(SecuredFilter.class.getName());
+
+    private String matches;
+    private String roles;
+    private String[]rolesArray;
+    private SecurePolicy policy = SecurePolicy.HIDE;
+
+    /**
+     * Factory for configuring immutable property filter.
+     */
+    public static final class SecuredFilterFactory implements 
ItemFactory<PropertyFilter> {
+        @Override
+        public String getName() {
+            return "Secured";
+        }
+
+        @Override
+        public PropertyFilter create(Map<String,String> parameters) {
+            return new SecuredFilter();
+        }
+
+        @Override
+        public Class<? extends PropertyFilter> getType() {
+            return PropertyFilter.class;
+        }
+    }
+
+    public String getMatches() {
+        return matches;
+    }
+
+    public SecuredFilter setMatches(String matches) {
+        this.matches = matches;
+        return this;
+    }
+
+    public String getRoles() {
+        return roles;
+    }
+
+    public SecuredFilter setRoles(String roles) {
+        this.roles = roles;
+        this.rolesArray = roles.split(",");
+        return this;
+    }
+
+    public SecurePolicy getPolicy() {
+        return policy;
+    }
+
+    public SecuredFilter setPolicy(SecurePolicy policy) {
+        this.policy = policy;
+        return this;
+    }
+
+    @Override
+    public PropertyValue filterProperty(PropertyValue value, FilterContext 
context) {
+        if(matches !=null){
+            if(!value.getKey().matches(matches)) {
+                return value;
+            }
+        }
+        Subject s = 
javax.security.auth.Subject.getSubject(AccessController.getContext());
+        for(Principal principal:s.getPrincipals()){
+            for(String role:rolesArray) {
+                if(principal.getName().equals(role)){
+                    return value;
+                }
+            }
+        }
+        switch(policy){
+            case THROW_EXCPETION:
+                throw new ConfigException("Unauthorized access to 
'"+value.getKey()+"', not in " + roles);
+            case WARN_ONLY:
+                LOG.warning("Unauthorized access to '"+value.getKey()+"', not 
in " + roles);
+                return value;
+            case HIDE:
+            default:
+                return null;
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "SecuredFilter{" +
+                "matches='" + matches + '\'' +
+                ", roles='" + roles + '\'' +
+                ", policy='" + policy + '\'' +
+                '}';
+    }
+
+    public enum SecurePolicy{
+        HIDE,
+        WARN_ONLY,
+        THROW_EXCPETION
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/FilteredPropertySource.java
----------------------------------------------------------------------
diff --git 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/FilteredPropertySource.java
 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/FilteredPropertySource.java
index 43d1836..fec8777 100644
--- 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/FilteredPropertySource.java
+++ 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/ext/FilteredPropertySource.java
@@ -142,6 +142,21 @@ public final class FilteredPropertySource extends 
BasePropertySource {
     }
 
     /**
+     * Removes the (first) given filter, if present.
+     * @param filterClass the class of the filter to remove, not null.
+     */
+    public void removePropertyFilter(Class<? extends PropertyFilter> 
filterClass){
+        synchronized(filters){
+            for(PropertyFilter f:filters){
+                if(f.getClass().equals(filterClass)){
+                    filters.remove(f);
+                    break;
+                }
+            }
+        }
+    }
+
+    /**
      * Access the current filters present.
      * @return a copy of the current filter list.
      */
@@ -152,13 +167,11 @@ public final class FilteredPropertySource extends 
BasePropertySource {
     }
 
     @Override
-    public String toString() {
+    protected String toStringValues() {
         synchronized (filters) {
-            return "FilteredPropertySource{" +
-                    "\n wrapped=" + wrapped +
-                    "\n filters=" + this.filters +
-                    "\n base=" + super.toString() +
-                    "\n}";
+            return  super.toStringValues() +
+                    "  wrapped=" + wrapped + '\n' +
+                    "  filters=" + this.filters + '\n';
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/CombinationPolicyReader.java
----------------------------------------------------------------------
diff --git 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/CombinationPolicyReader.java
 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/CombinationPolicyReader.java
index 4c9217d..9e31add 100644
--- 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/CombinationPolicyReader.java
+++ 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/CombinationPolicyReader.java
@@ -49,7 +49,7 @@ public class CombinationPolicyReader implements 
MetaConfigurationReader{
             throw new ConfigException("Only one combination policy can be 
applied.");
         }
         Node node = nodeList.item(0);
-        String type = node.getAttributes().getNamedItem("type").getNodeValue();
+        String type = 
node.getAttributes().getNamedItem("class").getNodeValue();
         LOG.finest("Loading combination policy configured: " + type);
         ItemFactory<PropertyValueCombinationPolicy> policyFactory = 
ItemFactoryManager.getInstance().getFactory(PropertyValueCombinationPolicy.class,
 type);
         PropertyValueCombinationPolicy policy = 
policyFactory.create(ComponentConfigurator.extractParameters(node));

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ComponentConfigurator.java
----------------------------------------------------------------------
diff --git 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ComponentConfigurator.java
 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ComponentConfigurator.java
index 93c50da..8832d98 100644
--- 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ComponentConfigurator.java
+++ 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ComponentConfigurator.java
@@ -18,6 +18,7 @@
  */
 package org.apache.tamaya.metamodel.internal;
 
+import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 
@@ -41,8 +42,17 @@ public final class ComponentConfigurator<T> {
     public static void configure(Object instance, Node node) {
         NodeList entryNodes = node.getChildNodes();
         Map<String,String> params = new HashMap<>();
+        for(int c=0;c<node.getAttributes().getLength();c++){
+            Node attr = node.getAttributes().item(c);
+            String key = attr.getNodeName();
+            String value = attr.getNodeValue();
+            params.put(key, value);
+        }
         for(int c=0;c<entryNodes.getLength();c++) {
             Node filterNode = entryNodes.item(c);
+            if(filterNode.getNodeType()!=Node.ELEMENT_NODE){
+                continue;
+            }
             if ("param".equals(filterNode.getNodeName())) {
                 String key = 
filterNode.getAttributes().getNamedItem("name").getNodeValue();
                 String value = filterNode.getTextContent();
@@ -71,8 +81,15 @@ public final class ComponentConfigurator<T> {
     }
 
     public static Map<String, String> extractParameters(Node node) {
-        NodeList entryNodes = node.getChildNodes();
         Map<String,String> params = new HashMap<>();
+        NamedNodeMap attributes = node.getAttributes();
+        for(int c=0;c<attributes.getLength();c++) {
+            Node pn = attributes.item(c);
+            String key = pn.getNodeName();
+            String value = pn.getNodeValue();
+            params.put(key, value);
+        }
+        NodeList entryNodes = node.getChildNodes();
         for(int c=0;c<entryNodes.getLength();c++) {
             Node filterNode = entryNodes.item(c);
             if ("param".equals(filterNode.getNodeName())) {

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ContextReader.java
----------------------------------------------------------------------
diff --git 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ContextReader.java
 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ContextReader.java
deleted file mode 100644
index 5e74f75..0000000
--- 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ContextReader.java
+++ /dev/null
@@ -1,181 +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.metamodel.internal;
-
-import org.apache.tamaya.metamodel.MetaContext;
-import org.apache.tamaya.metamodel.spi.MetaConfigurationReader;
-import org.apache.tamaya.metamodel.spi.SimpleResolver;
-import org.apache.tamaya.spi.ConfigurationContextBuilder;
-import org.apache.tamaya.spi.ServiceContextManager;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-import javax.annotation.Priority;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Logger;
-
-
-/**
- * Meta-configuration reader that reads the shared context data.
- */
-@Priority(-1)
-public class ContextReader implements MetaConfigurationReader {
-
-    private static final Logger LOG = 
Logger.getLogger(ContextReader.class.getName());
-
-    private Map<String,SimpleResolver> resolvers = new ConcurrentHashMap<>();
-
-    public ContextReader(){
-        for(SimpleResolver resolver: ServiceContextManager.getServiceContext()
-                .getServices(SimpleResolver.class)){
-            this.resolvers.put(resolver.getResolverId(), resolver);
-        }
-    }
-
-    public void addResolver(SimpleResolver resolver){
-        if(!this.resolvers.containsKey(resolver.getResolverId())) {
-            this.resolvers.put(resolver.getResolverId(), resolver);
-        }
-    }
-
-    public void removeResolver(SimpleResolver resolver){
-        this.resolvers.remove(resolver.getResolverId());
-    }
-
-    public Set<String> getResolverIds(){
-        return this.resolvers.keySet();
-    }
-
-    public SimpleResolver getResolver(String resolverKey){
-        return this.resolvers.get(resolverKey);
-    }
-
-    @Override
-    public void read(Document document, ConfigurationContextBuilder 
contextBuilder) {
-        NodeList nodeList = 
document.getDocumentElement().getElementsByTagName("context");
-        String contextName = null;
-        LOG.finer("Reading " + nodeList.getLength() + " meta context 
entries...");
-        for(int i=0;i<nodeList.getLength();i++){
-            Node node = nodeList.item(i);
-            if(node.getNodeName().equals("context")){
-                Node nameNode = node.getAttributes().getNamedItem("name");
-                if(nameNode!=null){
-                    contextName = nameNode.getTextContent();
-                }
-                MetaContext context = 
contextName!=null?MetaContext.getInstance(contextName):MetaContext.getDefaultInstance();
-                NodeList entryNodes = node.getChildNodes();
-                for(int c=0;c<entryNodes.getLength();c++){
-                    Node entryNode = entryNodes.item(c);
-                    if("context-entry".equals(entryNode.getNodeName())){
-                        String key = 
entryNode.getAttributes().getNamedItem("name").getNodeValue();
-                        String value = entryNode.getTextContent();
-                        resolvePlaceholders(value);
-                        LOG.finest("Applying context entry: " + key + '=' + 
value + " on " + contextName);
-                        context.setProperty(key, value);
-                    }
-                }
-            }
-        }
-    }
-
-    private String resolvePlaceholders(String value) {
-        StringBuilder result = new StringBuilder();
-        StringBuilder exp = new StringBuilder();
-        final int INVALUE = 0;
-        final int BEFORE_EXP = 1;
-        final int INEXP = 2;
-        int state = INVALUE;
-        StringTokenizer tokenizer = new StringTokenizer(value, "${}", true);
-        while(tokenizer.hasMoreTokens()){
-            String token = tokenizer.nextToken();
-            switch(token){
-                case "$":
-                    switch(state){
-                        case INVALUE:
-                        default:
-                            state = BEFORE_EXP;
-                            break;
-                        case BEFORE_EXP: // escaped
-                            result.append(token);
-                            state = INVALUE;
-                            break;
-                        case INEXP:
-                            exp.append(token);
-                            break;
-                    }
-                    break;
-                case "{":
-                    switch(state){
-                        case BEFORE_EXP:
-                            state = INEXP;
-                            break;
-                        case INVALUE:
-                        case INEXP:
-                        default:
-                            result.append(token);
-                            break;
-                    }
-                case "}":
-                    switch(state){
-                        case INVALUE:
-                            result.append(token);
-                            break;
-                        case INEXP:
-                            result.append(evaluateExpression(exp.toString()));
-                            exp.setLength(0);
-                            state = INVALUE;
-                            break;
-                        case BEFORE_EXP:
-                            result.append("$").append(token);
-                            state = INVALUE;
-                            break;
-                    }
-                    break;
-                default:
-                    result.append(token);
-            }
-        }
-        return result.toString();
-    }
-
-    private String evaluateExpression(String exp) {
-        String[] parts = exp.split(":", 2);
-        if(parts.length<2){
-            return "--{MISSING RESOLVER ID in "+exp+"}";
-        }
-        SimpleResolver resolver = this.resolvers.get(parts[0]);
-        if(resolver==null){
-            return "--{NO RESOLVER FOUND for "+exp+"}";
-        }
-        try{
-            String resolved = resolver.evaluate(parts[1]);
-            if(resolved==null) {
-                return "--{NOT RESOLVABLE:" + exp + "}";
-            }else{
-                return resolved;
-            }
-        }catch(Exception e){
-            return "--{ERROR:"+exp+":"+e+"}";
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/MetaContextReader.java
----------------------------------------------------------------------
diff --git 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/MetaContextReader.java
 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/MetaContextReader.java
new file mode 100644
index 0000000..8ec1c76
--- /dev/null
+++ 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/MetaContextReader.java
@@ -0,0 +1,185 @@
+/*
+ * 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.metamodel.internal;
+
+import org.apache.tamaya.metamodel.MetaContext;
+import org.apache.tamaya.metamodel.spi.MetaConfigurationReader;
+import org.apache.tamaya.metamodel.spi.SimpleResolver;
+import org.apache.tamaya.spi.ConfigurationContextBuilder;
+import org.apache.tamaya.spi.ServiceContextManager;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.annotation.Priority;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+
+/**
+ * Meta-configuration reader that reads the shared context data.
+ */
+@Priority(-1)
+public class MetaContextReader implements MetaConfigurationReader {
+
+    private static final Logger LOG = 
Logger.getLogger(MetaContextReader.class.getName());
+
+    private Map<String,SimpleResolver> resolvers = new ConcurrentHashMap<>();
+
+    public MetaContextReader(){
+        for(SimpleResolver resolver: ServiceContextManager.getServiceContext()
+                .getServices(SimpleResolver.class)){
+            this.resolvers.put(resolver.getResolverId(), resolver);
+        }
+    }
+
+    public void addResolver(SimpleResolver resolver){
+        if(!this.resolvers.containsKey(resolver.getResolverId())) {
+            this.resolvers.put(resolver.getResolverId(), resolver);
+        }
+    }
+
+    public void removeResolver(SimpleResolver resolver){
+        this.resolvers.remove(resolver.getResolverId());
+    }
+
+    public Set<String> getResolverIds(){
+        return this.resolvers.keySet();
+    }
+
+    public SimpleResolver getResolver(String resolverKey){
+        return this.resolvers.get(resolverKey);
+    }
+
+    @Override
+    public void read(Document document, ConfigurationContextBuilder 
contextBuilder) {
+        NodeList nodeList = 
document.getDocumentElement().getElementsByTagName("context");
+        LOG.finer("Reading " + nodeList.getLength() + " meta context 
entries...");
+        for(int i=0;i<nodeList.getLength();i++){
+            Node node = nodeList.item(i);
+            if(node.getNodeName().equals("context")){
+                MetaContext context = MetaContext.getInstance();
+                NodeList entryNodes = node.getChildNodes();
+                for(int c=0;c<entryNodes.getLength();c++){
+                    Node entryNode = entryNodes.item(c);
+                    if(entryNode.getNodeType()==Node.ELEMENT_NODE) {
+                        String key = entryNode.getNodeName();
+                        String value = entryNode.getTextContent();
+                        value = resolvePlaceholders(value);
+                        LOG.finest("MetaContext: " + key + '=' + value);
+                        context.setProperty(key, value);
+                    }
+                }
+            }
+        }
+    }
+
+    private String resolvePlaceholders(String value) {
+        StringBuilder result = new StringBuilder();
+        StringBuilder exp = new StringBuilder();
+        final int INVALUE = 0;
+        final int BEFORE_EXP = 1;
+        final int INEXP = 2;
+        int state = INVALUE;
+        StringTokenizer tokenizer = new StringTokenizer(value, "${}", true);
+        while(tokenizer.hasMoreTokens()){
+            String token = tokenizer.nextToken();
+            switch(token){
+                case "$":
+                    switch(state){
+                        case INVALUE:
+                        default:
+                            state = BEFORE_EXP;
+                            break;
+                        case BEFORE_EXP: // escaped
+                            result.append(token);
+                            state = INVALUE;
+                            break;
+                        case INEXP:
+                            exp.append(token);
+                            break;
+                    }
+                    break;
+                case "{":
+                    switch(state){
+                        case BEFORE_EXP:
+                            state = INEXP;
+                            break;
+                        case INVALUE:
+                        case INEXP:
+                        default:
+                            result.append(token);
+                            break;
+                    }
+                    break;
+                case "}":
+                    switch(state){
+                        case INVALUE:
+                            result.append(token);
+                            break;
+                        case INEXP:
+                            result.append(evaluateExpression(exp.toString()));
+                            exp.setLength(0);
+                            state = INVALUE;
+                            break;
+                        case BEFORE_EXP:
+                            result.append("$").append(token);
+                            state = INVALUE;
+                            break;
+                    }
+                    break;
+                default:
+                    switch(state){
+                        case INEXP:
+                            exp.append(token);
+                            break;
+                        default:
+                            result.append(token);
+                            break;
+                    }
+
+            }
+        }
+        return result.toString();
+    }
+
+    private String evaluateExpression(String exp) {
+        String[] parts = exp.split(":", 2);
+        if(parts.length<2){
+            return "--{MISSING RESOLVER ID in "+exp+"}";
+        }
+        SimpleResolver resolver = this.resolvers.get(parts[0]);
+        if(resolver==null){
+            return "--{NO RESOLVER FOUND for "+exp+"}";
+        }
+        try{
+            String resolved = resolver.evaluate(parts[1]);
+            if(resolved==null) {
+                return "--{NOT RESOLVABLE:" + exp + "}";
+            }else{
+                return resolved;
+            }
+        }catch(Exception e){
+            return "--{ERROR:"+exp+":"+e+"}";
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertyConverterReader.java
----------------------------------------------------------------------
diff --git 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertyConverterReader.java
 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertyConverterReader.java
index f82e92d..9490a78 100644
--- 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertyConverterReader.java
+++ 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertyConverterReader.java
@@ -18,14 +18,13 @@
  */
 package org.apache.tamaya.metamodel.internal;
 
+import org.apache.tamaya.ConfigException;
 import org.apache.tamaya.TypeLiteral;
 import org.apache.tamaya.metamodel.spi.ItemFactory;
 import org.apache.tamaya.metamodel.spi.ItemFactoryManager;
 import org.apache.tamaya.metamodel.spi.MetaConfigurationReader;
 import org.apache.tamaya.spi.ConfigurationContextBuilder;
 import org.apache.tamaya.spi.PropertyConverter;
-import org.apache.tamaya.spi.PropertySource;
-import org.apache.tamaya.spi.PropertySourceProvider;
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
@@ -49,38 +48,36 @@ public class PropertyConverterReader implements 
MetaConfigurationReader{
             return;
         }
         if(nodeList.getLength()>1){
-            LOG.warning("Multiple property-converters sections configured, 
onyl reading first...");
-            return;
+            throw new ConfigException("Only one single property-converters 
section allowed.");
         }
         nodeList = nodeList.item(0).getChildNodes();
         for(int i=0;i<nodeList.getLength();i++){
             Node node = nodeList.item(i);
-            try{
-                if(node.getNodeName().equals("converter")){
-                    String type = 
node.getAttributes().getNamedItem("type").getNodeValue();
-                    try {
-                        ItemFactory<PropertyConverter> converterFactory = 
ItemFactoryManager.getInstance().getFactory(PropertyConverter.class, type);
-                        if(converterFactory==null){
-                            LOG.severe("No such property converter: " + type);
-                            continue;
-                        }
-                        Map<String,String> params = 
ComponentConfigurator.extractParameters(node);
-                        PropertyConverter converter = 
converterFactory.create(params);
-                        if(converter!=null) {
-                            ComponentConfigurator.configure(converter, node);
-                            Class targetType = 
Class.forName(params.get("targetType"));
-                            LOG.finer("Adding converter for type " + 
targetType.getName() + ": " + converter.getClass());
-                            
contextBuilder.addPropertyConverters(TypeLiteral.of(targetType), converter);
-                        }
-                    } catch (Exception e) {
-                        LOG.log(Level.SEVERE, "Failed to configure 
PropertyConverter: " + type, e);
-                    }
-                }else if(node.getNodeName().equals("default-converters")){
-                    LOG.finer("Adding default property converters...");
-                    contextBuilder.addDefaultPropertyConverters();
+            if(node.getNodeType()!=Node.ELEMENT_NODE) {
+                continue;
+            }
+            String type = node.getNodeName();
+            if("defaults".equals(type)){
+                LOG.finer("Adding default property converters...");
+                contextBuilder.addDefaultPropertyConverters();
+                continue;
+            }
+            try {
+                ItemFactory<PropertyConverter> converterFactory = 
ItemFactoryManager.getInstance().getFactory(PropertyConverter.class, type);
+                if(converterFactory==null){
+                    LOG.severe("No such property converter: " + type);
+                    continue;
+                }
+                Map<String,String> params = 
ComponentConfigurator.extractParameters(node);
+                PropertyConverter converter = converterFactory.create(params);
+                if(converter!=null) {
+                    ComponentConfigurator.configure(converter, node);
+                    Class targetType = Class.forName(params.get("targetType"));
+                    LOG.finer("Adding converter for type " + 
targetType.getName() + ": " + converter.getClass());
+                    
contextBuilder.addPropertyConverters(TypeLiteral.of(targetType), converter);
                 }
-            }catch(Exception e){
-                LOG.log(Level.SEVERE, "Failed to read property converter 
configuration: " + node, e);
+            } catch (Exception e) {
+                LOG.log(Level.SEVERE, "Failed to configure PropertyConverter: 
" + type, e);
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertyFilterReader.java
----------------------------------------------------------------------
diff --git 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertyFilterReader.java
 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertyFilterReader.java
index 94bb6ec..be6fa2b 100644
--- 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertyFilterReader.java
+++ 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertyFilterReader.java
@@ -18,18 +18,17 @@
  */
 package org.apache.tamaya.metamodel.internal;
 
+import org.apache.tamaya.ConfigException;
 import org.apache.tamaya.metamodel.spi.ItemFactory;
 import org.apache.tamaya.metamodel.spi.ItemFactoryManager;
 import org.apache.tamaya.metamodel.spi.MetaConfigurationReader;
 import org.apache.tamaya.spi.ConfigurationContextBuilder;
 import org.apache.tamaya.spi.PropertyFilter;
-import org.apache.tamaya.spi.PropertySourceProvider;
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 
 import java.util.Map;
-import java.util.logging.Level;
 import java.util.logging.Logger;
 
 
@@ -48,33 +47,31 @@ public class PropertyFilterReader implements 
MetaConfigurationReader{
             return;
         }
         if(nodeList.getLength()>1){
-            LOG.warning("Multiple property-filters sections configured, onyl 
reading first...");
-            return;
+            throw new ConfigException("Only one single property-filters 
section allowed.");
         }
         nodeList = nodeList.item(0).getChildNodes();
         for(int i=0;i<nodeList.getLength();i++){
             Node node = nodeList.item(i);
-            try {
-                if ("filter".equals(node.getNodeName())) {
-                    String type = 
node.getAttributes().getNamedItem("type").getNodeValue();
-                    ItemFactory<PropertyFilter> filterFactory = 
ItemFactoryManager.getInstance().getFactory(PropertyFilter.class, type);
-                    if(filterFactory==null){
-                        LOG.severe("No such property filter: " + type);
-                        continue;
-                    }
-                    Map<String,String> params = 
ComponentConfigurator.extractParameters(node);
-                    PropertyFilter filter = filterFactory.create(params);
-                    if(filter!=null) {
-                        ComponentConfigurator.configure(filter, params);
-                        LOG.finer("Adding configured property filter: " + 
filter.getClass().getName());
-                        contextBuilder.addPropertyFilters(filter);
-                    }
-                } else if ("default-filters".equals(node.getNodeName())) {
-                    LOG.finer("Adding default property filters...");
-                    contextBuilder.addDefaultPropertyFilters();
-                }
-            }catch(Exception e){
-                LOG.log(Level.SEVERE, "Failed to read property filter 
configuration: " + node, e);
+            if(node.getNodeType()!=Node.ELEMENT_NODE) {
+                continue;
+            }
+            String type = node.getNodeName();
+            if ("defaults".equals(type)) {
+                LOG.finer("Adding default property filters...");
+                contextBuilder.addDefaultPropertyFilters();
+                continue;
+            }
+            ItemFactory<PropertyFilter> filterFactory = 
ItemFactoryManager.getInstance().getFactory(PropertyFilter.class, type);
+            if(filterFactory==null){
+                LOG.severe("No such property filter: " + type);
+                continue;
+            }
+            Map<String,String> params = 
ComponentConfigurator.extractParameters(node);
+            PropertyFilter filter = filterFactory.create(params);
+            if(filter!=null) {
+                ComponentConfigurator.configure(filter, params);
+                LOG.finer("Adding configured property filter: " + 
filter.getClass().getName());
+                contextBuilder.addPropertyFilters(filter);
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertySourceReader.java
----------------------------------------------------------------------
diff --git 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertySourceReader.java
 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertySourceReader.java
index ebcd8e0..a465146 100644
--- 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertySourceReader.java
+++ 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertySourceReader.java
@@ -18,7 +18,9 @@
  */
 package org.apache.tamaya.metamodel.internal;
 
-import org.apache.tamaya.metamodel.*;
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.metamodel.EnabledPropertySource;
+import org.apache.tamaya.metamodel.MetaContext;
 import org.apache.tamaya.metamodel.ext.EnabledPropertySourceProvider;
 import org.apache.tamaya.metamodel.ext.FilteredPropertySource;
 import org.apache.tamaya.metamodel.ext.RefreshablePropertySource;
@@ -53,57 +55,53 @@ public class PropertySourceReader implements 
MetaConfigurationReader{
             return;
         }
         if(nodeList.getLength()>1){
-            LOG.warning("Multiple property-sources sections configured, onyl 
reading first...");
-            return;
+            throw new ConfigException("Only one single property-source section 
allowed.");
         }
         nodeList = nodeList.item(0).getChildNodes();
         for(int i=0;i<nodeList.getLength();i++){
             Node node = nodeList.item(i);
-            try{
-                if(node.getNodeName().equals("source")){
-                    String type = 
node.getAttributes().getNamedItem("type").getNodeValue();
-                    try {
-                        ItemFactory<PropertySource> sourceFactory = 
ItemFactoryManager.getInstance().getFactory(PropertySource.class, type);
-                        if(sourceFactory==null){
-                            LOG.severe("No such property source: " + type);
-                            continue;
-                        }
-                        Map<String,String> params = 
ComponentConfigurator.extractParameters(node);
-                        PropertySource ps = sourceFactory.create(params);
-                        if(ps!=null) {
-                            ComponentConfigurator.configure(ps, params);
-                            ps = decoratePropertySource(ps, contextBuilder, 
node, params);
-                            LOG.finer("Adding configured property source: " + 
ps.getName());
-                            contextBuilder.addPropertySources(ps);
-                        }
-                    } catch (Exception e) {
-                        LOG.log(Level.SEVERE, "Failed to configure 
PropertySource: " + type, e);
-                    }
-                }else if(node.getNodeName().equals("source-provider")){
-                    String type = 
node.getAttributes().getNamedItem("type").getNodeValue();
-                    try {
-                        ItemFactory<PropertySourceProvider> providerFactory = 
ItemFactoryManager.getInstance().getFactory(PropertySourceProvider.class, type);
-                        if(providerFactory==null){
-                            LOG.severe("No such property source provider: " + 
type);
-                            continue;
-                        }
-                        Map<String,String> params = 
ComponentConfigurator.extractParameters(node);
-                        PropertySourceProvider prov = 
providerFactory.create(params);
-                        if(prov!=null) {
-                            ComponentConfigurator.configure(prov, node);
-                            prov = decoratePropertySourceProvider(prov, 
contextBuilder, node, params);
-                            LOG.finer("Adding configured property source 
provider: " + prov.getClass().getName());
-                            
contextBuilder.addPropertySources(prov.getPropertySources());
-                        }
-                    } catch (Exception e) {
-                        LOG.log(Level.SEVERE, "Failed to configure 
PropertySourceProvider: " + type, e);
+            if(node.getNodeType()!=Node.ELEMENT_NODE) {
+                continue;
+            }
+            String type = node.getNodeName();
+            if("defaults".equals(type)){
+                LOG.fine("Adding default property sources.");
+                contextBuilder.addDefaultPropertySources();
+                continue;
+            }
+            try {
+                ItemFactory<PropertySource> sourceFactory = 
ItemFactoryManager.getInstance().getFactory(PropertySource.class, type);
+                if (sourceFactory != null) {
+                    LOG.fine("Property source found: " + type);
+                    Map<String, String> params = 
ComponentConfigurator.extractParameters(node);
+                    PropertySource ps = sourceFactory.create(params);
+                    if (ps != null) {
+                        ComponentConfigurator.configure(ps, params);
+                        ps = decoratePropertySource(ps, node, params);
+                        LOG.finer("Adding configured property source: " + 
ps.getName());
+                        contextBuilder.addPropertySources(ps);
                     }
-                }else if(node.getNodeName().equals("default-sources")){
-                    LOG.finer("Adding default property sources.");
-                    contextBuilder.addDefaultPropertySources();
                 }
-            }catch(Exception e){
-                LOG.log(Level.SEVERE, "Failed to read property source 
configuration: " + node, e);
+            } catch (Exception e) {
+                LOG.log(Level.SEVERE, "Failed to configure PropertySource: " + 
type, e);
+                continue;
+            }
+            try {
+                ItemFactory<PropertySourceProvider> providerFactory = 
ItemFactoryManager.getInstance().getFactory(PropertySourceProvider.class, type);
+                if(providerFactory==null){
+                    LOG.fine("No such property source provider: " + type);
+                    continue;
+                }
+                Map<String,String> params = 
ComponentConfigurator.extractParameters(node);
+                PropertySourceProvider prov = providerFactory.create(params);
+                if(prov!=null) {
+                    ComponentConfigurator.configure(prov, node);
+                    prov = decoratePropertySourceProvider(prov, node, params);
+                    LOG.finer("Adding configured property source provider: " + 
prov.getClass().getName());
+                    
contextBuilder.addPropertySources(prov.getPropertySources());
+                }
+            } catch (Exception e) {
+                LOG.log(Level.SEVERE, "Failed to configure 
PropertySourceProvider: " + type, e);
             }
         }
     }
@@ -111,37 +109,38 @@ public class PropertySourceReader implements 
MetaConfigurationReader{
     /**
      * Decorates a property source to be refreshable or filtered.
      * @param ps the wrapped property source
-     * @param contextBuilder
      *@param configNode the XML config node
      * @param params the extracted parameter list   @return the property 
source to be added to the context.
      */
-    private PropertySource decoratePropertySource(PropertySource ps, 
ConfigurationContextBuilder contextBuilder, Node configNode, Map<String, 
String> params){
+    private PropertySource decoratePropertySource(PropertySource ps, Node 
configNode, Map<String, String> params){
         Node refreshableVal = 
configNode.getAttributes().getNamedItem("refreshable");
         if(refreshableVal!=null && 
Boolean.parseBoolean(refreshableVal.getNodeValue())){
-            if(!(ps instanceof Refreshable)){
-                ps = RefreshablePropertySource.of(params, ps);
-            }
+            ps = RefreshablePropertySource.of(params, ps);
+        }
+        Node enabledVal = configNode.getAttributes().getNamedItem("enabled");
+        if(enabledVal!=null){
+            ps = new EnabledPropertySource(ps,
+                    MetaContext.getInstance().getProperties(),
+                    enabledVal.getNodeValue());
         }
         NodeList childNodes = configNode.getChildNodes();
         for(int i=0;i<childNodes.getLength();i++){
             Node node = childNodes.item(i);
-            if("filter".equals(node.getNodeName())) {
+            if("filters".equals(node.getNodeName())){
                 ps = FilteredPropertySource.of(ps);
-                configureFilter((FilteredPropertySource) ps, node);
+                NodeList filterNodes = node.getChildNodes();
+                for(int f=0;f<filterNodes.getLength();f++) {
+                    Node filterNode = filterNodes.item(f);
+                    configureFilter((FilteredPropertySource) ps, filterNode);
+                }
             }
         }
-        Node enabledVal = configNode.getAttributes().getNamedItem("enabled");
-        if(enabledVal!=null){
-            ps = new EnabledPropertySource(ps,
-                    MetaContext.getDefaultInstance().getProperties(),
-                    enabledVal.getNodeValue());
-        }
         return ps;
     }
 
     private void configureFilter(FilteredPropertySource ps, Node filterNode) {
         try {
-            String type = 
filterNode.getAttributes().getNamedItem("type").getNodeValue();
+            String type = filterNode.getNodeName();
             ItemFactory<PropertyFilter> filterFactory = 
ItemFactoryManager.getInstance().getFactory(PropertyFilter.class, type);
             if(filterFactory==null){
                 LOG.severe("No such property filter: " + type);
@@ -162,21 +161,20 @@ public class PropertySourceReader implements 
MetaConfigurationReader{
     /**
      * Decorates a property source provider to be refreshable or filtered.
      * @param prov the property source provider to be wrapped.
-     * @param contextBuilder
-     *@param configNode the XML config node
+     * @param configNode the XML config node
      * @param params the extracted parameter list   @return the property 
source provider to be added to the context.
      */
-    private PropertySourceProvider 
decoratePropertySourceProvider(PropertySourceProvider prov, 
ConfigurationContextBuilder contextBuilder, Node configNode, Map<String, 
String> params){
+    private PropertySourceProvider 
decoratePropertySourceProvider(PropertySourceProvider prov, Node configNode, 
Map<String, String> params){
         Node refreshableVal = 
configNode.getAttributes().getNamedItem("refreshable");
+        // Refreshable
         if(refreshableVal!=null && 
Boolean.parseBoolean(refreshableVal.getNodeValue())){
-            if(!(prov instanceof Refreshable)){
-                prov = RefreshablePropertySourceProvider.of(params, prov);
-            }
+            prov = RefreshablePropertySourceProvider.of(params, prov);
         }
+        // Enabled
         Node enabledVal = configNode.getAttributes().getNamedItem("enabled");
         if(enabledVal!=null){
             prov = new EnabledPropertySourceProvider(prov,
-                    MetaContext.getDefaultInstance().getProperties(),
+                    MetaContext.getInstance().getProperties(),
                     enabledVal.getNodeValue());
         }
         return prov;

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/FilePropertySourceFactory.java
----------------------------------------------------------------------
diff --git 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/FilePropertySourceFactory.java
 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/FilePropertySourceFactory.java
index d3961d4..5acfefd 100644
--- 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/FilePropertySourceFactory.java
+++ 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/FilePropertySourceFactory.java
@@ -52,10 +52,8 @@ public final class FilePropertySourceFactory extends 
ResourcePropertySourceFacto
 
     @Override
     protected String example() {
-        return "<source type=\""+getName()+"\">\n" +
-                "  <param name=\"location\">c:/temp/config.xml</param>\n" +
-                "  <param name=\"formats\">xml-properties</param>\n" +
-                "</source>\n";
+        return "<file location=\"c:/temp/config.xml\"\n" +
+                "     formats=\"xml-properties\")>\n";
     }
 
     @Override
@@ -63,9 +61,9 @@ public final class FilePropertySourceFactory extends 
ResourcePropertySourceFacto
         try {
             Path path = Paths.get(location);
             if(!path.toFile().exists()){
-                LOG.info("Cannot read resource '" + location + "': no such 
file.");
+                LOG.info("Cannot read file '" + location + "': no such file.");
             }else if(!path.toFile().canRead()){
-                LOG.info("Cannot read resource '" + location + "': not 
readable.");
+                LOG.info("Cannot read file '" + location + "': not readable.");
             }
             return path.toUri().toURL();
         } catch (MalformedURLException e) {

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/ResourcePropertySourceFactory.java
----------------------------------------------------------------------
diff --git 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/ResourcePropertySourceFactory.java
 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/ResourcePropertySourceFactory.java
index a36fd7f..0248100 100644
--- 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/ResourcePropertySourceFactory.java
+++ 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/ResourcePropertySourceFactory.java
@@ -41,15 +41,13 @@ public class ResourcePropertySourceFactory extends 
URLPropertySourceFactory{
 
     @Override
     public String getName() {
-        return "classpath";
+        return "resource";
     }
 
 
     protected String example() {
-        return "<source type=\""+getName()+"\">\n" +
-                "  <param name=\"location\">/META-INF/config.xml</param>\n" +
-                "  <param name=\"formats\">xml-properties</param>\n" +
-                "</source>\n";
+        return "<resource location=\"META-INF/config.xml\"\n" +
+                "     formats=\"xml-properties\")>\n";
     }
 
     protected URL createResource(String location) {

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/ResourcePropertySourceProviderFactory.java
----------------------------------------------------------------------
diff --git 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/ResourcePropertySourceProviderFactory.java
 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/ResourcePropertySourceProviderFactory.java
index 77f22d4..db5c9b9 100644
--- 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/ResourcePropertySourceProviderFactory.java
+++ 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/ResourcePropertySourceProviderFactory.java
@@ -41,7 +41,7 @@ public class ResourcePropertySourceProviderFactory implements 
ItemFactory<Proper
 
     @Override
     public String getName() {
-        return "resource";
+        return "resources";
     }
 
     @Override
@@ -97,10 +97,8 @@ public class ResourcePropertySourceProviderFactory 
implements ItemFactory<Proper
     }
 
     protected String example() {
-        return "<source-provider type=\""+getName()+"\">\n" +
-                "  <param name=\"location\">/META-INF/**/config.xml</param>\n" 
+
-                "  <param name=\"formats\">xml-properties</param>\n" +
-                "</source-provider>\n";
+        return "<resources location\"/META-INF/**/config.xml\"\n" +
+                "          formats=\"xml-properties\"\n/>";
     }
 
     protected Collection<URL> createResources(String location) {

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/URLPropertySourceFactory.java
----------------------------------------------------------------------
diff --git 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/URLPropertySourceFactory.java
 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/URLPropertySourceFactory.java
index 342eebb..7cf6ab6 100644
--- 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/URLPropertySourceFactory.java
+++ 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/factories/URLPropertySourceFactory.java
@@ -68,10 +68,8 @@ public class URLPropertySourceFactory implements 
ItemFactory<PropertySource>{
     }
 
     protected String example() {
-        return "<source type=\""+getName()+"\">\n" +
-                "  <param 
name=\"location\">http://127.0.0.1:1110/config.xml</param>\n" +
-                "  <param name=\"formats\">xml-properties</param>\n" +
-                "</source>\n";
+        return "<url location=\"http://127.0.0.1:1110/config.xml\"\n"; +
+                "    formats=\"xml-properties\"\n/>";
     }
 
     protected URL createResource(String location) {

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/resolver/PropertiesResolver.java
----------------------------------------------------------------------
diff --git 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/resolver/PropertiesResolver.java
 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/resolver/PropertiesResolver.java
index 4edbe3e..4e70e03 100644
--- 
a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/resolver/PropertiesResolver.java
+++ 
b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/resolver/PropertiesResolver.java
@@ -48,7 +48,7 @@ public final class PropertiesResolver implements 
SimpleResolver{
         if(mainParts.length==1){
             return evaluate(expression, null);
         }else{
-            return evaluate(expression, 
mainParts[1].trim().substring("default=".length()));
+            return evaluate(mainParts[0], 
mainParts[1].trim().substring("default=".length()));
         }
 
     }
@@ -59,7 +59,7 @@ public final class PropertiesResolver implements 
SimpleResolver{
             return null;
         }
         switch(parts[0]){
-            case "sys":
+            case "system":
                 return System.getProperty(parts[1],defaultValue);
             case "env":
                 String val = System.getenv(parts[1]);
@@ -68,13 +68,8 @@ public final class PropertiesResolver implements 
SimpleResolver{
                 }
                 return val;
             case "ctx":
-                if(parts.length==3){
-                    return MetaContext.getInstance(parts[1])
-                            .getProperty(parts[2], defaultValue);
-                }else{
-                    return MetaContext.getDefaultInstance()
-                            .getProperty(parts[1], defaultValue);
-                }
+                return MetaContext.getInstance()
+                        .getProperty(parts[1], defaultValue);
             default:
                 return null;
         }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/resources/META-INF/services/org.apache.tamaya.metamodel.spi.ItemFactory
----------------------------------------------------------------------
diff --git 
a/metamodel/src/main/resources/META-INF/services/org.apache.tamaya.metamodel.spi.ItemFactory
 
b/metamodel/src/main/resources/META-INF/services/org.apache.tamaya.metamodel.spi.ItemFactory
index 7b73763..951f4b8 100644
--- 
a/metamodel/src/main/resources/META-INF/services/org.apache.tamaya.metamodel.spi.ItemFactory
+++ 
b/metamodel/src/main/resources/META-INF/services/org.apache.tamaya.metamodel.spi.ItemFactory
@@ -24,3 +24,10 @@ 
org.apache.tamaya.metamodel.internal.factories.SysPropertiesFactory
 org.apache.tamaya.metamodel.internal.factories.URLPropertySourceFactory
 
 
org.apache.tamaya.metamodel.internal.factories.ResourcePropertySourceProviderFactory
+
+org.apache.tamaya.metamodel.ImmutableFilter$ImmutableFilterFactory
+org.apache.tamaya.metamodel.MapFilter$MapFilterFactory
+org.apache.tamaya.metamodel.HideFilter$HideFilterFactory
+org.apache.tamaya.metamodel.CachedFilter$CachedFilterFactory
+org.apache.tamaya.metamodel.MaskFilter$MaskFilterFactory
+org.apache.tamaya.metamodel.SecuredFilter$SecuredFilterFactory

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/main/resources/META-INF/services/org.apache.tamaya.metamodel.spi.MetaConfigurationReader
----------------------------------------------------------------------
diff --git 
a/metamodel/src/main/resources/META-INF/services/org.apache.tamaya.metamodel.spi.MetaConfigurationReader
 
b/metamodel/src/main/resources/META-INF/services/org.apache.tamaya.metamodel.spi.MetaConfigurationReader
index cd2af30..79b9249 100644
--- 
a/metamodel/src/main/resources/META-INF/services/org.apache.tamaya.metamodel.spi.MetaConfigurationReader
+++ 
b/metamodel/src/main/resources/META-INF/services/org.apache.tamaya.metamodel.spi.MetaConfigurationReader
@@ -20,7 +20,7 @@
 org.apache.tamaya.metamodel.internal.PropertyFilterReader
 org.apache.tamaya.metamodel.internal.PropertyConverterReader
 org.apache.tamaya.metamodel.internal.PropertySourceReader
-org.apache.tamaya.metamodel.internal.ContextReader
+org.apache.tamaya.metamodel.internal.MetaContextReader
 org.apache.tamaya.metamodel.internal.CombinationPolicyReader
 org.apache.tamaya.metamodel.internal.PropertyFilterOrderingReader
 org.apache.tamaya.metamodel.internal.PropertySourceOrderingReader
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/10d711e6/metamodel/src/test/java/org/apache/tamaya/metamodel/ext/IntegrationTest.java
----------------------------------------------------------------------
diff --git 
a/metamodel/src/test/java/org/apache/tamaya/metamodel/ext/IntegrationTest.java 
b/metamodel/src/test/java/org/apache/tamaya/metamodel/ext/IntegrationTest.java
index 4462520..b461603 100644
--- 
a/metamodel/src/test/java/org/apache/tamaya/metamodel/ext/IntegrationTest.java
+++ 
b/metamodel/src/test/java/org/apache/tamaya/metamodel/ext/IntegrationTest.java
@@ -16,16 +16,23 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-
 package org.apache.tamaya.metamodel.ext;
 
 import org.apache.tamaya.Configuration;
 import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.metamodel.CachedFilter;
+import org.apache.tamaya.metamodel.MapFilter;
 import org.apache.tamaya.metamodel.MetaConfiguration;
+import org.apache.tamaya.metamodel.MetaContext;
+import org.apache.tamaya.spi.PropertyConverter;
 import org.junit.Test;
 
 import java.net.URL;
+import java.util.List;
 
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
 import static junit.framework.TestCase.assertNotNull;
 import static junit.framework.TestCase.assertTrue;
 
@@ -50,6 +57,104 @@ public class IntegrationTest {
         assertTrue(config.getContext().getPropertyFilters().isEmpty());
     }
 
+    @Test
+    public void testMetaContextConfig(){
+        Configuration config = 
MetaConfiguration.createConfiguration(getConfig("IntegrationTests/context-test.xml"));
+        assertNotNull(config);
+        assertTrue(config.getProperties().isEmpty());
+        assertTrue(config.getContext().getPropertyConverters().isEmpty());
+        assertTrue(config.getContext().getPropertyFilters().isEmpty());
+        MetaContext ctx = MetaContext.getInstance();
+        assertFalse(ctx.getProperties().isEmpty());
+        assertEquals(ctx.getId(), ctx.getProperty("_id"));
+        assertEquals("NONE", ctx.getProperty("app"));
+        assertEquals("DEV", ctx.getProperty("stage"));
+        assertEquals(".", ctx.getProperty("configdir"));
+
+    }
+
+    @Test
+    public void testDefaultConvertersConfig(){
+        Configuration config = 
MetaConfiguration.createConfiguration(getConfig("IntegrationTests/default-propertyconverters-test.xml"));
+        assertNotNull(config);
+        assertTrue(config.getContext().getPropertySources().isEmpty());
+        assertTrue(config.getProperties().isEmpty());
+        assertFalse(config.getContext().getPropertyConverters().isEmpty());
+        assertTrue(config.getContext().getPropertyFilters().isEmpty());
+        assertEquals(config.getContext(),
+                ConfigurationProvider.getConfigurationContextBuilder()
+                        .addDefaultPropertyConverters()
+                        .build());
+
+    }
+
+    @Test
+    public void testDefaultPropertySourcesConfig(){
+        Configuration config = 
MetaConfiguration.createConfiguration(getConfig("IntegrationTests/default-propertysources-test.xml"));
+        assertNotNull(config);
+        assertFalse(config.getProperties().isEmpty());
+        assertFalse(config.getContext().getPropertySources().isEmpty());
+        assertTrue(config.getContext().getPropertyConverters().isEmpty());
+        assertTrue(config.getContext().getPropertyFilters().isEmpty());
+        assertEquals(config.getContext(),
+                ConfigurationProvider.getConfigurationContextBuilder()
+                        .addDefaultPropertySources()
+                        .build());
+
+    }
+
+    @Test
+    public void testDefaultPropertyFiltersConfig(){
+        Configuration config = 
MetaConfiguration.createConfiguration(getConfig("IntegrationTests/default-propertyfilters-test.xml"));
+        assertNotNull(config);
+        assertTrue(config.getProperties().isEmpty());
+        assertTrue(config.getContext().getPropertySources().isEmpty());
+        assertTrue(config.getContext().getPropertyConverters().isEmpty());
+        assertFalse(config.getContext().getPropertyFilters().isEmpty());
+        assertEquals(config.getContext(),
+                ConfigurationProvider.getConfigurationContextBuilder()
+                        .addDefaultPropertyFilters()
+                        .build());
+
+    }
+
+    @Test
+    public void testPropertyFiltersConfig(){
+        Configuration config = 
MetaConfiguration.createConfiguration(getConfig("IntegrationTests/propertyfilters-test.xml"));
+        assertNotNull(config);
+        assertTrue(config.getProperties().isEmpty());
+        assertTrue(config.getContext().getPropertySources().isEmpty());
+        assertTrue(config.getContext().getPropertyConverters().isEmpty());
+        assertFalse(config.getContext().getPropertyFilters().isEmpty());
+        assertEquals(1, config.getContext().getPropertyFilters().size());
+        assertTrue(config.getContext().getPropertyFilters().get(0) instanceof 
CachedFilter);
+    }
+
+    @Test
+    public void testPropertyConvertersConfig(){
+        Configuration config = 
MetaConfiguration.createConfiguration(getConfig("IntegrationTests/propertyconverters-test.xml"));
+        assertNotNull(config);
+        assertTrue(config.getProperties().isEmpty());
+        assertTrue(config.getContext().getPropertySources().isEmpty());
+        assertFalse(config.getContext().getPropertyConverters().isEmpty());
+        assertTrue(config.getContext().getPropertyFilters().isEmpty());
+        assertEquals(1, config.getContext().getPropertyConverters().size());
+        List<PropertyConverter<Object>> converters = 
config.getContext().getPropertyConverters(TypeLiteral.of(String.class));
+        assertTrue(converters.get(0).getClass().equals(MyConverter.class));
+    }
+
+    @Test
+    public void testPropertySourcesConfig(){
+        Configuration config = 
MetaConfiguration.createConfiguration(getConfig("IntegrationTests/propertysources-test.xml"));
+        assertNotNull(config);
+        assertFalse(config.getProperties().isEmpty());
+        assertFalse(config.getContext().getPropertySources().isEmpty());
+        assertTrue(config.getContext().getPropertyConverters().isEmpty());
+        assertTrue(config.getContext().getPropertyFilters().isEmpty());
+        assertEquals(2, config.getContext().getPropertySources().size());
+        assertTrue(config.getContext().getPropertySources().get(0) instanceof 
MyPropertySource);
+    }
+
     private URL getConfig(String resource) {
         return getClass().getClassLoader().getResource(resource);
     }


Reply via email to