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 2017/03/05 23:29:41 UTC

[1/6] incubator-tamaya git commit: TAMAYA-252: Unified PropertyValue builder API.

Repository: incubator-tamaya
Updated Branches:
  refs/heads/master b59c1ae26 -> 8ad767b48


TAMAYA-252: Unified PropertyValue builder API.


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

Branch: refs/heads/master
Commit: 8ad767b484f2e9bb6247b14ca53c8395b773ebe0
Parents: b2dddeb
Author: anatole <an...@apache.org>
Authored: Mon Mar 6 00:28:58 2017 +0100
Committer: anatole <an...@apache.org>
Committed: Mon Mar 6 00:29:34 2017 +0100

----------------------------------------------------------------------
 .../org/apache/tamaya/spi/FilterContext.java    |  47 ++++---
 .../apache/tamaya/spi/FilterContextTest.java    |  71 +++++++++--
 .../core/internal/DefaultConfiguration.java     |   2 +-
 .../tamaya/core/internal/PropertyFiltering.java | 123 ++++++++-----------
 .../core/internal/PropertySourceComparator.java |   4 +-
 .../core/testdata/TestPropertyFilter.java       |   2 +-
 .../testdata/TestRemovingPropertyFilter.java    |   4 +-
 7 files changed, 152 insertions(+), 101 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/8ad767b4/code/api/src/main/java/org/apache/tamaya/spi/FilterContext.java
----------------------------------------------------------------------
diff --git a/code/api/src/main/java/org/apache/tamaya/spi/FilterContext.java b/code/api/src/main/java/org/apache/tamaya/spi/FilterContext.java
index d5c7850..e3f4465 100644
--- a/code/api/src/main/java/org/apache/tamaya/spi/FilterContext.java
+++ b/code/api/src/main/java/org/apache/tamaya/spi/FilterContext.java
@@ -18,6 +18,8 @@
  */
 package org.apache.tamaya.spi;
 
+import org.apache.tamaya.Configuration;
+
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
@@ -30,7 +32,9 @@ import java.util.Objects;
  */
 public class FilterContext {
     /** The key. */
-    private final String key;
+    private final PropertyValue value;
+    /** tHE CURRENT CONTEXT. */
+    private final ConfigurationContext context;
     @Experimental
     private Map<String, PropertyValue> configEntries = new HashMap();
     @Experimental
@@ -38,35 +42,50 @@ public class FilterContext {
 
 
     /**
-     * Creates a new FilterContext.
-     * @param key the key under evaluation, not null.
+     * Creates a new FilterContext, for filtering of a multi value access
+     * using {@link Configuration#getProperties()}.
+     * @param value the value under evaluation, not null.
      * @param configEntries the raw configuration data available in the current evaluation context, not null.
+     * @param context the current context, not null.
      */
-    public FilterContext(String key, Map<String,PropertyValue> configEntries) {
+    public FilterContext(PropertyValue value, Map<String,PropertyValue> configEntries, ConfigurationContext context) {
         this.singlePropertyScoped = false;
-        this.key = Objects.requireNonNull(key);
+        this.value = Objects.requireNonNull(value);
+        this.context = Objects.requireNonNull(context);
         this.configEntries.putAll(configEntries);
         this.configEntries = Collections.unmodifiableMap(this.configEntries);
     }
 
-    public FilterContext(String key, PropertyValue value) {
+    /**
+     * Creates a new FilterContext, for filtering of a single value access
+     * using {@link Configuration#getProperties()}.
+     * @param value the value under evaluation, not null.
+     * @param context the current context, not null.
+     */
+    public FilterContext(PropertyValue value, ConfigurationContext context) {
         this.singlePropertyScoped = true;
-        this.key = Objects.requireNonNull(key);
-        if(value!=null) {
-            this.configEntries.put(value.getKey(), value);
-        }
+        this.context = Objects.requireNonNull(context);
+        this.value = Objects.requireNonNull(value);
         this.configEntries = Collections.unmodifiableMap(this.configEntries);
     }
 
     /**
-     * Get the key accessed. This information is very useful to evaluate additional metadata needed to determine/
+     * Get the current context.
+     * @return the current context, not null.
+     */
+    public ConfigurationContext getContext(){
+        return context;
+    }
+
+    /**
+     * Get the property value under evaluation. This information is very useful to evaluate additional metadata needed to determine/
      * control further aspects of the conversion.
      *
      * @return the key. This may be null in case where a default value has to be converted and no unique underlying
      * key/value configuration is present.
      */
-    public String getKey() {
-        return key;
+    public PropertyValue getProperty() {
+        return value;
     }
 
     /**
@@ -106,7 +125,7 @@ public class FilterContext {
 
     @Override
     public String toString() {
-        return "FilterContext{key='" + key + "', configEntries=" + configEntries.keySet() + '}';
+        return "FilterContext{value='" + value + "', configEntries=" + configEntries.keySet() + '}';
     }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/8ad767b4/code/api/src/test/java/org/apache/tamaya/spi/FilterContextTest.java
----------------------------------------------------------------------
diff --git a/code/api/src/test/java/org/apache/tamaya/spi/FilterContextTest.java b/code/api/src/test/java/org/apache/tamaya/spi/FilterContextTest.java
index d8d9380..3d0e1f0 100644
--- a/code/api/src/test/java/org/apache/tamaya/spi/FilterContextTest.java
+++ b/code/api/src/test/java/org/apache/tamaya/spi/FilterContextTest.java
@@ -18,9 +18,11 @@
  */
 package org.apache.tamaya.spi;
 
+import org.apache.tamaya.TypeLiteral;
 import org.junit.Test;
 
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import static org.junit.Assert.*;
@@ -31,17 +33,18 @@ import static org.junit.Assert.*;
 public class FilterContextTest {
     @Test
     public void getKey() throws Exception {
-        FilterContext ctx = new FilterContext("getKey",
-                new HashMap<String,PropertyValue>());
-        assertEquals("getKey", ctx.getKey());
+        PropertyValue val = PropertyValue.of("getKey", "v", "");
+        FilterContext ctx = new FilterContext(val,
+                new HashMap<String,PropertyValue>(), new TestConfigContext());
+        assertEquals(val, ctx.getProperty());
     }
 
     @Test
     public void isSinglePropertyScoped() throws Exception {
-        FilterContext ctx = new FilterContext("isSinglePropertyScoped",
-                new HashMap<String,PropertyValue>());
+        PropertyValue val = PropertyValue.of("isSinglePropertyScoped", "v", "");
+        FilterContext ctx = new FilterContext(val, new HashMap<String,PropertyValue>(), new TestConfigContext());
         assertEquals(false, ctx.isSinglePropertyScoped());
-        ctx = new FilterContext("isSinglePropertyScoped", PropertyValue.of("isSinglePropertyScoped", "val", "test"));
+        ctx = new FilterContext(val, new TestConfigContext());
         assertEquals(true, ctx.isSinglePropertyScoped());
     }
 
@@ -51,7 +54,8 @@ public class FilterContextTest {
         for(int i=0;i<10;i++) {
             config.put("key-"+i, PropertyValue.of("key-"+i, "value-"+i, "test"));
         }
-        FilterContext ctx = new FilterContext("getMetaEntries", config);
+        PropertyValue val = PropertyValue.of("getConfigEntries", "v", "");
+        FilterContext ctx = new FilterContext(val, config, new TestConfigContext());
         assertEquals(config, ctx.getConfigEntries());
         assertTrue(config != ctx.getConfigEntries());
     }
@@ -62,13 +66,62 @@ public class FilterContextTest {
         for(int i=0;i<2;i++) {
             config.put("key-"+i, PropertyValue.of("key-"+i, "value-"+i, "test"));
         }
-        FilterContext ctx = new FilterContext("testToString", config);
+        PropertyValue val = PropertyValue.of("testToString", "val", "mySource");
+        FilterContext ctx = new FilterContext(val, config, new TestConfigContext());
         String toString = ctx.toString();
         assertNotNull(toString);
-        assertTrue(toString.contains("FilterContext{key='testToString', configEntries=["));
+        assertTrue(toString.contains("FilterContext{value='PropertyValue{key='testToString', value='val', source='val'}', configEntries=["));
         assertTrue(toString.contains("key-0"));
         assertTrue(toString.contains("key-1"));
         assertTrue(toString.endsWith("}"));
     }
 
+    private static class TestConfigContext implements ConfigurationContext{
+
+        @Override
+        public void addPropertySources(PropertySource... propertySources) {
+
+        }
+
+        @Override
+        public List<PropertySource> getPropertySources() {
+            return null;
+        }
+
+        @Override
+        public PropertySource getPropertySource(String name) {
+            return null;
+        }
+
+        @Override
+        public <T> void addPropertyConverter(TypeLiteral<T> type, PropertyConverter<T> propertyConverter) {
+
+        }
+
+        @Override
+        public Map<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters() {
+            return null;
+        }
+
+        @Override
+        public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> type) {
+            return null;
+        }
+
+        @Override
+        public List<PropertyFilter> getPropertyFilters() {
+            return null;
+        }
+
+        @Override
+        public PropertyValueCombinationPolicy getPropertyValueCombinationPolicy() {
+            return null;
+        }
+
+        @Override
+        public ConfigurationContextBuilder toBuilder() {
+            return null;
+        }
+    }
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/8ad767b4/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
index 8ad7489..0b25b00 100644
--- a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
@@ -82,7 +82,7 @@ public class DefaultConfiguration implements Configuration {
         if(value==null || value.getValue()==null){
             return null;
         }
-        value = PropertyFiltering.applyFilter(key, value, configurationContext);
+        value = PropertyFiltering.applyFilter(value, configurationContext);
         if(value!=null){
             return value.getValue();
         }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/8ad767b4/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyFiltering.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyFiltering.java b/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyFiltering.java
index 932d38c..79cca09 100644
--- a/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyFiltering.java
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyFiltering.java
@@ -24,10 +24,8 @@ import org.apache.tamaya.spi.PropertyFilter;
 import org.apache.tamaya.spi.PropertySource;
 import org.apache.tamaya.spi.PropertyValue;
 
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -52,95 +50,76 @@ public final class PropertyFiltering{
      */
     private PropertyFiltering(){}
 
-    public static PropertyValue applyFilter(String key, PropertyValue value, ConfigurationContext configurationContext) {
+    /**
+     * Filters a single value.
+     * @param value the raw value, not null.
+     * @param context the context
+     * @return the filtered value, inclusing null.
+     */
+    public static PropertyValue applyFilter(PropertyValue value, ConfigurationContext context) {
+        FilterContext filterContext = new FilterContext(value, context);
+        return filterValue(filterContext);
+    }
+
+    /**
+     * Filters all properties.
+     * @param rawProperties the unfiltered properties, not null.
+     * @param context the context
+     * @return the filtered value, inclusing null.
+     */
+    public static Map<String, PropertyValue> applyFilters(Map<String, PropertyValue> rawProperties, ConfigurationContext context) {
+        Map<String, PropertyValue> result = new HashMap<>();
         // Apply filters to values, prevent values filtered to null!
-        for (int i = 0; i < MAX_FILTER_LOOPS; i++) {
-            boolean changed = false;
-            // Apply filters to values, prevent values filtered to null!
-            FilterContext filterContext = new FilterContext(key, value);
-            for (PropertyFilter filter : configurationContext.getPropertyFilters()) {
-                PropertyValue newValue = filter.filterProperty(value, filterContext);
-                if (newValue != null && !newValue.equals(value)) {
-                    changed = true;
-                    if (LOG.isLoggable(Level.FINEST)) {
-                        LOG.finest("Filter - " + value + " -> " + newValue + " by " + filter);
-                    }
-                } else if (value != null && !value.equals(newValue)) {
-                    changed = true;
-                    if (LOG.isLoggable(Level.FINEST)) {
-                        LOG.finest("Filter - " + value + " -> " + newValue + " by " + filter);
-                    }
-                }
-                value = newValue;
-            }
-            if (!changed) {
-                LOG.finest("Finishing filter loop, no changes detected.");
-                break;
-            } else {
-                if (i == (MAX_FILTER_LOOPS - 1)) {
-                    if (LOG.isLoggable(Level.WARNING)) {
-                        LOG.warning("Maximal filter loop count reached, aborting filter evaluation after cycles: " + i);
-                    }
-                } else {
-                    LOG.finest("Repeating filter loop, changes detected.");
-                }
+        for (Map.Entry<String, PropertyValue> entry : rawProperties.entrySet()) {
+            FilterContext filterContext = new FilterContext(entry.getValue(), rawProperties, context);
+            PropertyValue filtered = filterValue(filterContext);
+            if(filtered!=null){
+                result.put(filtered.getKey(), filtered);
             }
         }
-        return value;
+        return result;
     }
 
-    public static Map<String, PropertyValue> applyFilters(Map<String, PropertyValue> inputMap, ConfigurationContext configurationContext) {
-        Map<String, PropertyValue> resultMap = new HashMap<>(inputMap);
-        // Apply filters to values, prevent values filtered to null!
+    /**
+     * Basic filter logic.
+     * @param context the filter context, not null.
+     * @return the filtered value.
+     */
+    private static PropertyValue filterValue(FilterContext context) {
+        PropertyValue inputValue = context.getProperty();
+        PropertyValue filteredValue = inputValue;
+
         for (int i = 0; i < MAX_FILTER_LOOPS; i++) {
-            AtomicInteger changes = new AtomicInteger();
-            for (Map.Entry<String, PropertyValue> entry : inputMap.entrySet()) {
-                FilterContext filterContext = new FilterContext(entry.getKey(), inputMap);
-                for (PropertyFilter filter : configurationContext.getPropertyFilters()) {
-                    final String k = entry.getKey();
-                    final PropertyValue v = entry.getValue();
-                    PropertyValue newValue = filter.filterProperty(v, filterContext);
-                    if (newValue != null && !newValue.equals(v)) {
-                        changes.incrementAndGet();
-                        LOG.finest("Filter - " + k + ": " + v + " -> " + newValue + " by " + filter);
-                    } else if (v != null && !v.equals(newValue)) {
-                        changes.incrementAndGet();
-                        LOG.finest("Filter - " + k + ": " + v + " -> " + newValue + " by " + filter);
-                    }
-                    // Remove null values
-                    if (null != newValue) {
-                        resultMap.put(k, newValue);
-                    }
-                    else{
-                        resultMap.remove(k);
-                    }
+            int changes = 0;
+            for (PropertyFilter filter : context.getContext().getPropertyFilters()) {
+                filteredValue = filter.filterProperty(inputValue, context);
+                if (filteredValue != null && !filteredValue.equals(inputValue)) {
+                    changes++;
+                    LOG.finest("Filter - " + inputValue + " -> " + filteredValue + " by " + filter);
+                }
+                if(filteredValue==null){
+                    LOG.finest("Filter removed entry - " + inputValue + ": " + filter);
+                    break;
+                }else{
+                    inputValue = filteredValue;
                 }
             }
-            if (changes.get() == 0) {
+            if (changes == 0) {
                 LOG.finest("Finishing filter loop, no changes detected.");
                 break;
+            } else if (filteredValue == null) {
+                break;
             } else {
                 if (i == (MAX_FILTER_LOOPS - 1)) {
                     if (LOG.isLoggable(Level.WARNING)) {
                         LOG.warning("Maximal filter loop count reached, aborting filter evaluation after cycles: " + i);
                     }
                 } else {
-                    LOG.finest("Repeating filter loop, changes detected: " + changes.get());
+                    LOG.finest("Repeating filter loop, changes detected: " + changes);
                 }
-                changes.set(0);
-            }
-        }
-        return resultMap;
-    }
-
-    private static Map<String, String> filterMetadata(Map<String, String> inputMap) {
-        Map<String,String> result = new HashMap<>();
-        for(Map.Entry<String,String> en:inputMap.entrySet()){
-            if(en.getKey().startsWith("_")){
-                result.put(en.getKey(), en.getValue());
             }
         }
-        return Collections.unmodifiableMap(result);
+        return filteredValue;
     }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/8ad767b4/code/core/src/main/java/org/apache/tamaya/core/internal/PropertySourceComparator.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/PropertySourceComparator.java b/code/core/src/main/java/org/apache/tamaya/core/internal/PropertySourceComparator.java
index 7e9c503..35e147f 100644
--- a/code/core/src/main/java/org/apache/tamaya/core/internal/PropertySourceComparator.java
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/PropertySourceComparator.java
@@ -88,10 +88,10 @@ public class PropertySourceComparator implements Comparator<PropertySource>, Ser
 //        PropertyValue ordinalValue = propertySource.get(PropertySource.TAMAYA_ORDINAL);
 //        if(ordinalValue!=null){
 //            try{
-//                return Integer.parseInt(ordinalValue.getValue().trim());
+//                return Integer.parseInt(ordinalValue.getProperty().trim());
 //            }catch(Exception e){
 //                LOG.finest("Failed to parse ordinal from " + PropertySource.TAMAYA_ORDINAL +
-//                        " in " + propertySource.getName()+": "+ordinalValue.getValue());
+//                        " in " + propertySource.getName()+": "+ordinalValue.getProperty());
 //            }
 //        }
 //        try {

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/8ad767b4/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyFilter.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyFilter.java b/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyFilter.java
index f0ae4d3..96f80a6 100644
--- a/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyFilter.java
+++ b/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyFilter.java
@@ -31,7 +31,7 @@ import javax.annotation.Priority;
 public class TestPropertyFilter implements PropertyFilter{
     @Override
     public PropertyValue filterProperty(PropertyValue valueToBeFiltered, FilterContext context) {
-        if("name4".equals(context.getKey())){
+        if("name4".equals(context.getProperty().getKey())){
             return valueToBeFiltered.toBuilder()
                     .setValue(valueToBeFiltered.getValue() + "(filtered)")
                     .build();

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/8ad767b4/code/core/src/test/java/org/apache/tamaya/core/testdata/TestRemovingPropertyFilter.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/testdata/TestRemovingPropertyFilter.java b/code/core/src/test/java/org/apache/tamaya/core/testdata/TestRemovingPropertyFilter.java
index e984962..488ea0b 100644
--- a/code/core/src/test/java/org/apache/tamaya/core/testdata/TestRemovingPropertyFilter.java
+++ b/code/core/src/test/java/org/apache/tamaya/core/testdata/TestRemovingPropertyFilter.java
@@ -32,10 +32,10 @@ import javax.annotation.Priority;
 public class TestRemovingPropertyFilter implements PropertyFilter{
     @Override
     public PropertyValue filterProperty(PropertyValue valueToBeFiltered, FilterContext context) {
-        if("name5".equals(context.getKey())){
+        if("name5".equals(context.getProperty().getKey())){
             return null;
         }
-        else if("name3".equals(context.getKey())){
+        else if("name3".equals(context.getProperty().getKey())){
             return valueToBeFiltered.toBuilder().setValue(
                     "Mapped to name: " + ConfigurationProvider.getConfiguration().get("name"))
                     .build();


[2/6] incubator-tamaya git commit: TAMAYA-252: Unified PropertyValue API and usage, also separating key, value, source and other meta-data and defining a clear builder policy.

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/test/java/org/apache/tamaya/core/internal/converters/ConverterTestsPropertySource.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/internal/converters/ConverterTestsPropertySource.java b/code/core/src/test/java/org/apache/tamaya/core/internal/converters/ConverterTestsPropertySource.java
index 121e331..d09ed8d 100644
--- a/code/core/src/test/java/org/apache/tamaya/core/internal/converters/ConverterTestsPropertySource.java
+++ b/code/core/src/test/java/org/apache/tamaya/core/internal/converters/ConverterTestsPropertySource.java
@@ -30,6 +30,11 @@ import java.util.Map;
 public class ConverterTestsPropertySource implements PropertySource{
 
     @Override
+    public int getOrdinal() {
+        return 0;
+    }
+
+    @Override
     public String getName(){
         return "ConverterTestsPropertySource";
     }
@@ -238,7 +243,7 @@ public class ConverterTestsPropertySource implements PropertySource{
     }
 
     @Override
-    public Map<String, String> getProperties() {
+    public Map<String, PropertyValue> getProperties() {
         return Collections.emptyMap();
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/test/java/org/apache/tamaya/core/propertysource/BasePropertySourceTest.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/propertysource/BasePropertySourceTest.java b/code/core/src/test/java/org/apache/tamaya/core/propertysource/BasePropertySourceTest.java
index 37cc86a..9c2fc60 100644
--- a/code/core/src/test/java/org/apache/tamaya/core/propertysource/BasePropertySourceTest.java
+++ b/code/core/src/test/java/org/apache/tamaya/core/propertysource/BasePropertySourceTest.java
@@ -21,13 +21,10 @@ package org.apache.tamaya.core.propertysource;
 import org.apache.tamaya.core.internal.PropertySourceComparator;
 import org.apache.tamaya.spi.PropertySource;
 import org.apache.tamaya.spi.PropertyValue;
-import org.apache.tamaya.spi.PropertyValueBuilder;
 import org.junit.Assert;
 import org.junit.Test;
 
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
 
 public class BasePropertySourceTest {
 
@@ -47,7 +44,7 @@ public class BasePropertySourceTest {
             }
 
             @Override
-            public Map<String, String> getProperties() {
+            public Map<String, PropertyValue> getProperties() {
                 return Collections.emptyMap();
             }
         };
@@ -61,7 +58,7 @@ public class BasePropertySourceTest {
 
     @Test
     public void testGet() {
-        Assert.assertEquals("1000", new OverriddenOrdinalPropertySource().get(PropertySource.TAMAYA_ORDINAL).get(PropertySource.TAMAYA_ORDINAL));
+        Assert.assertEquals(1000, new OverriddenOrdinalPropertySource().getOrdinal());
     }
 
     private static class OverriddenOrdinalPropertySource extends BasePropertySource {
@@ -76,10 +73,10 @@ public class BasePropertySourceTest {
         }
 
         @Override
-        public Map<String, String> getProperties() {
-            Map<String, String> map = new HashMap<>(1);
-            map.put(PropertySource.TAMAYA_ORDINAL, "1000");
-            return map;
+        public Map<String, PropertyValue> getProperties() {
+            Map<String,PropertyValue> result = new HashMap<>(1);
+            result.put(PropertySource.TAMAYA_ORDINAL, PropertyValue.of(PropertySource.TAMAYA_ORDINAL, "1000", getName()));
+            return result;
         }
     }
 
@@ -95,10 +92,10 @@ public class BasePropertySourceTest {
         }
 
         @Override
-        public Map<String, String> getProperties() {
-            Map<String, String> map = new HashMap<>(1);
-            map.put(PropertySource.TAMAYA_ORDINAL, "invalid");
-            return map;
+        public Map<String, PropertyValue> getProperties() {
+            Map<String,PropertyValue> result = new HashMap<>(1);
+            result.put(PropertySource.TAMAYA_ORDINAL, PropertyValue.of(PropertySource.TAMAYA_ORDINAL, "invalid", getName()));
+            return result;
         }
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/test/java/org/apache/tamaya/core/propertysource/CLIPropertySourceTest.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/propertysource/CLIPropertySourceTest.java b/code/core/src/test/java/org/apache/tamaya/core/propertysource/CLIPropertySourceTest.java
index dde63e5..20126f3 100644
--- a/code/core/src/test/java/org/apache/tamaya/core/propertysource/CLIPropertySourceTest.java
+++ b/code/core/src/test/java/org/apache/tamaya/core/propertysource/CLIPropertySourceTest.java
@@ -34,25 +34,25 @@ public class CLIPropertySourceTest {
         assertTrue(ps.getProperties().isEmpty());
         CLIPropertySource.initMainArgs("-a", "b");
         assertFalse(ps.getProperties().isEmpty());
-        assertEquals(ps.getProperties().get("a"), "b");
+        assertEquals(ps.getProperties().get("a").getValue(), "b");
         CLIPropertySource.initMainArgs("--c");
         assertFalse(ps.getProperties().isEmpty());
-        assertEquals(ps.getProperties().get("c"), "c");
+        assertEquals(ps.getProperties().get("c").getValue(), "c");
         CLIPropertySource.initMainArgs("sss");
         assertFalse(ps.getProperties().isEmpty());
-        assertEquals(ps.getProperties().get("sss"), "sss");
+        assertEquals(ps.getProperties().get("sss").getValue(), "sss");
         CLIPropertySource.initMainArgs("-a", "b", "--c", "sss", "--val=vvv");
         assertFalse(ps.getProperties().isEmpty());
-        assertEquals(ps.getProperties().get("a"), "b");
-        assertEquals(ps.getProperties().get("c"), "c");
-        assertEquals(ps.getProperties().get("sss"), "sss");
+        assertEquals(ps.getProperties().get("a").getValue(), "b");
+        assertEquals(ps.getProperties().get("c").getValue(), "c");
+        assertEquals(ps.getProperties().get("sss").getValue(), "sss");
     // getProperties() throws Exception {
         System.setProperty("main.args", "-a b\t--c sss  ");
         ps = new CLIPropertySource();
         assertFalse(ps.getProperties().isEmpty());
         System.clearProperty("main.args");
-        assertEquals(ps.getProperties().get("a"), "b");
-        assertEquals(ps.getProperties().get("c"), "c");
-        assertEquals(ps.getProperties().get("sss"), "sss");
+        assertEquals(ps.getProperties().get("a").getValue(), "b");
+        assertEquals(ps.getProperties().get("c").getValue(), "c");
+        assertEquals(ps.getProperties().get("sss").getValue(), "sss");
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/test/java/org/apache/tamaya/core/propertysource/EnvironmentPropertySourceTest.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/propertysource/EnvironmentPropertySourceTest.java b/code/core/src/test/java/org/apache/tamaya/core/propertysource/EnvironmentPropertySourceTest.java
index 96d530a..2781158 100644
--- a/code/core/src/test/java/org/apache/tamaya/core/propertysource/EnvironmentPropertySourceTest.java
+++ b/code/core/src/test/java/org/apache/tamaya/core/propertysource/EnvironmentPropertySourceTest.java
@@ -18,6 +18,7 @@
  */
 package org.apache.tamaya.core.propertysource;
 
+import org.apache.tamaya.spi.PropertyValue;
 import org.junit.Test;
 
 import java.util.Map;
@@ -45,16 +46,16 @@ public class EnvironmentPropertySourceTest {
     @Test
     public void testGet() throws Exception {
         for (Map.Entry<String, String> envEntry : System.getenv().entrySet()) {
-            assertEquals(envPropertySource.get(envEntry.getKey()).get(envEntry.getKey()), envEntry.getValue());
+            assertEquals(envPropertySource.get(envEntry.getKey()).getValue(), envEntry.getValue());
         }
     }
 
     @Test
     public void testGetProperties() throws Exception {
-        Map<String, String> props = envPropertySource.getProperties();
-        for(Map.Entry<String,String> en: props.entrySet()){
+        Map<String, PropertyValue> props = envPropertySource.getProperties();
+        for(Map.Entry<String,PropertyValue> en: props.entrySet()){
             if(!en.getKey().startsWith("_")){
-                assertEquals(System.getenv(en.getKey()), en.getValue());
+                assertEquals(System.getenv(en.getKey()), en.getValue().getValue());
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/test/java/org/apache/tamaya/core/propertysource/PropertiesFilePropertySourceTest.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/propertysource/PropertiesFilePropertySourceTest.java b/code/core/src/test/java/org/apache/tamaya/core/propertysource/PropertiesFilePropertySourceTest.java
index 39aeb3b..d11b48e 100644
--- a/code/core/src/test/java/org/apache/tamaya/core/propertysource/PropertiesFilePropertySourceTest.java
+++ b/code/core/src/test/java/org/apache/tamaya/core/propertysource/PropertiesFilePropertySourceTest.java
@@ -34,15 +34,15 @@ public class PropertiesFilePropertySourceTest {
     public void testGetOrdinal() {
         Assert.assertEquals(0, testfilePropertySource.getOrdinal());
         Assert.assertEquals(Integer.parseInt(overrideOrdinalPropertySource.get(PropertySource.TAMAYA_ORDINAL)
-                .get(PropertySource.TAMAYA_ORDINAL)),
+                .getValue()),
                 overrideOrdinalPropertySource.getOrdinal());
     }
 
 
     @Test
     public void testGet() {
-        Assert.assertEquals("val3", testfilePropertySource.get("key3").get("key3"));
-        Assert.assertEquals("myval5", overrideOrdinalPropertySource.get("mykey5").get("mykey5"));
+        Assert.assertEquals("val3", testfilePropertySource.get("key3").getValue());
+        Assert.assertEquals("myval5", overrideOrdinalPropertySource.get("mykey5").getValue());
         Assert.assertNull(testfilePropertySource.get("nonpresentkey"));
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/test/java/org/apache/tamaya/core/propertysource/SimplePropertySourceTest.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/propertysource/SimplePropertySourceTest.java b/code/core/src/test/java/org/apache/tamaya/core/propertysource/SimplePropertySourceTest.java
index 34902fa..2edc466 100644
--- a/code/core/src/test/java/org/apache/tamaya/core/propertysource/SimplePropertySourceTest.java
+++ b/code/core/src/test/java/org/apache/tamaya/core/propertysource/SimplePropertySourceTest.java
@@ -19,6 +19,7 @@
 package org.apache.tamaya.core.propertysource;
 
 import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.spi.PropertyValue;
 import org.junit.Test;
 
 import java.net.URL;
@@ -40,8 +41,8 @@ public class SimplePropertySourceTest {
 
         assertThat(source, notNullValue());
         assertThat(source.getProperties(), aMapWithSize(2)); // double the size for .source values.
-        assertThat(source.getProperties(), hasEntry("a", "b"));
-        assertThat(source.getProperties(), hasEntry("b", "1"));
+        assertThat(source.getProperties(), hasEntry("a", PropertyValue.of("a", "b", resource.toString())));
+        assertThat(source.getProperties(), hasEntry("b", PropertyValue.of("b", "1", resource.toString())));
 
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/test/java/org/apache/tamaya/core/propertysource/SystemPropertySourceTest.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/propertysource/SystemPropertySourceTest.java b/code/core/src/test/java/org/apache/tamaya/core/propertysource/SystemPropertySourceTest.java
index e6dd5bd..2b2b61e 100644
--- a/code/core/src/test/java/org/apache/tamaya/core/propertysource/SystemPropertySourceTest.java
+++ b/code/core/src/test/java/org/apache/tamaya/core/propertysource/SystemPropertySourceTest.java
@@ -37,9 +37,9 @@ public class SystemPropertySourceTest {
         // test the default ordinal
         Assert.assertEquals(SystemPropertySource.DEFAULT_ORDINAL, testPropertySource.getOrdinal());
 
-        // set the ordinal to 1000
-        System.setProperty(PropertySource.TAMAYA_ORDINAL, "1000");
-        Assert.assertEquals(1000, new SystemPropertySource().getOrdinal());
+        // set the ordinal to 1001
+        System.setProperty(PropertySource.TAMAYA_ORDINAL, "1001");
+        Assert.assertEquals(1001, new SystemPropertySource().getOrdinal());
         // currently its not possible to change ordinal at runtime
 
         // reset it to not destroy other tests!!
@@ -72,30 +72,20 @@ public class SystemPropertySourceTest {
 
         // cleanup
         System.clearProperty("test");
-
-        // no modifaction
-        try {
-            testPropertySource.getProperties().put("add.new.keys", "must throw exception");
-            Assert.fail(UnsupportedOperationException.class.getName() + " expected");
-        }
-        catch (UnsupportedOperationException e) {
-            // expected -> all is fine
-        }
     }
 
-    private void checkWithSystemProperties(Map<String, String> toCheck) {
+    private void checkWithSystemProperties(Map<String,PropertyValue> toCheck) {
         Properties systemEntries = System.getProperties();
-
-        Assert.assertEquals("size of System.getProperties().entrySet() must be the same as SystemPropertySrouce.getProperties().entrySet()",
-                            systemEntries.size(), toCheck.size()/2);
-
-        for (Map.Entry<String, String> propertySourceEntry : toCheck.entrySet()) {
+        int num = 0;
+        for (PropertyValue propertySourceEntry : toCheck.values()) {
             if(propertySourceEntry.getKey().startsWith("_")){
                 continue; // meta entry
             }
+            num ++;
             Assert.assertEquals("Entry values for key '" + propertySourceEntry.getKey() + "' do not match",
                                 systemEntries.getProperty(propertySourceEntry.getKey()), propertySourceEntry.getValue());
         }
-
+        Assert.assertEquals("size of System.getProperties().entrySet() must be the same as SystemPropertySrouce.getProperties().entrySet()",
+                systemEntries.size(), num);
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/test/java/org/apache/tamaya/core/provider/JavaConfigurationProviderTest.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/provider/JavaConfigurationProviderTest.java b/code/core/src/test/java/org/apache/tamaya/core/provider/JavaConfigurationProviderTest.java
index 26e5291..f7c7f7c 100644
--- a/code/core/src/test/java/org/apache/tamaya/core/provider/JavaConfigurationProviderTest.java
+++ b/code/core/src/test/java/org/apache/tamaya/core/provider/JavaConfigurationProviderTest.java
@@ -42,7 +42,7 @@ public class JavaConfigurationProviderTest {
             String key = "confkey" + i;
             String value = "javaconf-value" + i;
 
-            assertThat(value, equalTo(propertySource.get(key).get(key)));
+            assertThat(value, equalTo(propertySource.get(key).getValue()));
 
             // check if we had our key in configuration.current
             assertThat(getConfiguration().getProperties().containsKey(key), is(true));

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSource.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSource.java b/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSource.java
index 6c8751c..09d86f1 100644
--- a/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSource.java
+++ b/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyDefaultSource.java
@@ -19,6 +19,7 @@
 package org.apache.tamaya.core.testdata;
 
 import org.apache.tamaya.core.propertysource.BasePropertySource;
+import org.apache.tamaya.spi.PropertyValue;
 
 import java.util.Collections;
 import java.util.HashMap;
@@ -29,12 +30,12 @@ import java.util.Map;
  */
 public class TestPropertyDefaultSource extends BasePropertySource{
 
-    private Map<String,String> properties = new HashMap<>();
+    private Map<String,PropertyValue> properties = new HashMap<>();
 
     public TestPropertyDefaultSource() {
         super(100);
-        properties.put("name","Anatole");
-        properties.put("name2","Sabine");
+        properties.put("name",PropertyValue.of("name", "Anatole", "test"));
+        properties.put("name2",PropertyValue.of("name2", "Sabine", "test"));
         properties = Collections.unmodifiableMap(properties);
     }
 
@@ -44,7 +45,7 @@ public class TestPropertyDefaultSource extends BasePropertySource{
     }
 
     @Override
-    public Map<String, String> getProperties() {
+    public Map<String, PropertyValue> getProperties() {
         return properties;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyFilter.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyFilter.java b/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyFilter.java
index 071cbb1..f0ae4d3 100644
--- a/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyFilter.java
+++ b/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertyFilter.java
@@ -20,6 +20,7 @@ package org.apache.tamaya.core.testdata;
 
 import org.apache.tamaya.spi.FilterContext;
 import org.apache.tamaya.spi.PropertyFilter;
+import org.apache.tamaya.spi.PropertyValue;
 
 import javax.annotation.Priority;
 
@@ -29,9 +30,11 @@ import javax.annotation.Priority;
 @Priority(100)
 public class TestPropertyFilter implements PropertyFilter{
     @Override
-    public String filterProperty(String valueToBeFiltered, FilterContext context) {
+    public PropertyValue filterProperty(PropertyValue valueToBeFiltered, FilterContext context) {
         if("name4".equals(context.getKey())){
-            return valueToBeFiltered + "(filtered)";
+            return valueToBeFiltered.toBuilder()
+                    .setValue(valueToBeFiltered.getValue() + "(filtered)")
+                    .build();
         }
         return valueToBeFiltered;
     }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java b/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
index 5706478..b93be17 100644
--- a/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
+++ b/code/core/src/test/java/org/apache/tamaya/core/testdata/TestPropertySourceProvider.java
@@ -21,6 +21,7 @@ package org.apache.tamaya.core.testdata;
 import org.apache.tamaya.core.propertysource.BasePropertySource;
 import org.apache.tamaya.spi.PropertySource;
 import org.apache.tamaya.spi.PropertySourceProvider;
+import org.apache.tamaya.spi.PropertyValue;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -48,14 +49,14 @@ public class TestPropertySourceProvider implements PropertySourceProvider {
 
     private static class MyPropertySource extends BasePropertySource {
 
-        private Map<String, String> properties = new HashMap<>();
+        private Map<String, PropertyValue> properties = new HashMap<>();
 
         public MyPropertySource() {
             super(200);
-            properties.put("name", "Robin");
-            properties.put("name3", "Lukas");
-            properties.put("name4", "Sereina");
-            properties.put("name5", "Benjamin");
+            properties.put("name", PropertyValue.of("name", "Robin", "test"));
+            properties.put("name3", PropertyValue.of("name3", "Lukas", "test"));
+            properties.put("name4", PropertyValue.of("name4", "Sereina", "test"));
+            properties.put("name5", PropertyValue.of("name5", "Benjamin", "test"));
             properties = Collections.unmodifiableMap(properties);
         }
 
@@ -65,7 +66,7 @@ public class TestPropertySourceProvider implements PropertySourceProvider {
         }
 
         @Override
-        public Map<String, String> getProperties() {
+        public Map<String, PropertyValue> getProperties() {
             return properties;
         }
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/test/java/org/apache/tamaya/core/testdata/TestRemovingPropertyFilter.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/testdata/TestRemovingPropertyFilter.java b/code/core/src/test/java/org/apache/tamaya/core/testdata/TestRemovingPropertyFilter.java
index 7a5b7a8..e984962 100644
--- a/code/core/src/test/java/org/apache/tamaya/core/testdata/TestRemovingPropertyFilter.java
+++ b/code/core/src/test/java/org/apache/tamaya/core/testdata/TestRemovingPropertyFilter.java
@@ -21,6 +21,7 @@ package org.apache.tamaya.core.testdata;
 import org.apache.tamaya.ConfigurationProvider;
 import org.apache.tamaya.spi.FilterContext;
 import org.apache.tamaya.spi.PropertyFilter;
+import org.apache.tamaya.spi.PropertyValue;
 
 import javax.annotation.Priority;
 
@@ -30,12 +31,14 @@ import javax.annotation.Priority;
 @Priority(200)
 public class TestRemovingPropertyFilter implements PropertyFilter{
     @Override
-    public String filterProperty(String valueToBeFiltered, FilterContext context) {
+    public PropertyValue filterProperty(PropertyValue valueToBeFiltered, FilterContext context) {
         if("name5".equals(context.getKey())){
             return null;
         }
         else if("name3".equals(context.getKey())){
-            return "Mapped to name: " + ConfigurationProvider.getConfiguration().get("name");
+            return valueToBeFiltered.toBuilder().setValue(
+                    "Mapped to name: " + ConfigurationProvider.getConfiguration().get("name"))
+                    .build();
         }
         return valueToBeFiltered;
     }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimplePropertySource.java
----------------------------------------------------------------------
diff --git a/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimplePropertySource.java b/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimplePropertySource.java
index 6d05e19..ebc054d 100644
--- a/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimplePropertySource.java
+++ b/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimplePropertySource.java
@@ -19,6 +19,7 @@
 package org.apache.tamaya.examples.custompropertysource;
 
 import org.apache.tamaya.core.propertysource.BasePropertySource;
+import org.apache.tamaya.spi.PropertyValue;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -31,7 +32,7 @@ import java.util.Properties;
 public class SimplePropertySource extends BasePropertySource {
 
     public static final String CONFIG_PROPERTIES_LOCATION = "META-INF/MyOtherConfigProperties.properties";
-    private Map<String,String> props = new HashMap<>();
+    private Map<String,PropertyValue> props = new HashMap<>();
 
     public SimplePropertySource() throws IOException {
         URL url = ClassLoader.getSystemClassLoader().getResource(CONFIG_PROPERTIES_LOCATION);
@@ -41,7 +42,9 @@ public class SimplePropertySource extends BasePropertySource {
             properties.load(is);
 
             for(Map.Entry en: properties.entrySet()){
-                props.put(en.getKey().toString(), en.getValue().toString());
+                props.put(en.getKey().toString(),
+                        PropertyValue.of(en.getKey().toString(), en.getValue().toString(),
+                                getName()));
             }
         }
         finally{
@@ -55,7 +58,7 @@ public class SimplePropertySource extends BasePropertySource {
     }
 
     @Override
-    public Map<String, String> getProperties() {
+    public Map<String, PropertyValue> getProperties() {
         return props;
     }
 }
\ No newline at end of file


[4/6] incubator-tamaya git commit: TAMAYA-252: Clarified PropertyValue API.

Posted by an...@apache.org.
TAMAYA-252: Clarified PropertyValue API.


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

Branch: refs/heads/master
Commit: 8c0081b9a8f6123f080bdd4c4b33dc0c62fde451
Parents: b59c1ae
Author: anatole <an...@apache.org>
Authored: Fri Mar 3 22:27:02 2017 +0100
Committer: anatole <an...@apache.org>
Committed: Mon Mar 6 00:29:34 2017 +0100

----------------------------------------------------------------------
 .../org/apache/tamaya/spi/PropertyValue.java    | 60 +++++++++++++----
 .../apache/tamaya/spi/PropertyValueBuilder.java | 70 +++++++++++++++++---
 2 files changed, 108 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/8c0081b9/code/api/src/main/java/org/apache/tamaya/spi/PropertyValue.java
----------------------------------------------------------------------
diff --git a/code/api/src/main/java/org/apache/tamaya/spi/PropertyValue.java b/code/api/src/main/java/org/apache/tamaya/spi/PropertyValue.java
index 30afeab..0332b85 100644
--- a/code/api/src/main/java/org/apache/tamaya/spi/PropertyValue.java
+++ b/code/api/src/main/java/org/apache/tamaya/spi/PropertyValue.java
@@ -18,6 +18,7 @@
  */
 package org.apache.tamaya.spi;
 
+import java.io.Serializable;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
@@ -29,18 +30,21 @@ import java.util.Objects;
  * it is possible to create a PropertyValue with a null value. Nevertheless in all cases the provider source (typically
  * the name of the PropertySource) must be set.
  */
-public final class PropertyValue {
+public final class PropertyValue implements Serializable{
+    private static final long serialVersionUID = 1L;
     /** The requested key. */
     private String key;
+    /** The value. */
+    private String value;
     /** Additional metadata provided by the provider. */
-    private Map<String,String> configEntries = new HashMap<>();
+    private Map<String,String> metaEntries = new HashMap<>();
 
     PropertyValue(PropertyValueBuilder builder){
         this.key = builder.key;
-        if(builder.contextData!=null) {
-            this.configEntries.putAll(builder.contextData);
+        this.value = Objects.requireNonNull(builder.value);
+        if(builder.metaEntries !=null) {
+            this.metaEntries.putAll(builder.metaEntries);
         }
-        this.configEntries.put(key, Objects.requireNonNull(builder.value));
     }
 
     /**
@@ -51,8 +55,8 @@ public final class PropertyValue {
      */
     private PropertyValue(String key, String value, String source){
         this.key = Objects.requireNonNull(key, "key is required.");
-        this.configEntries.put(key, value);
-        this.configEntries.put("_"+key+".source", Objects.requireNonNull(source, "source is required."));
+        this.value = Objects.requireNonNull(value);
+        this.metaEntries.put("_"+key+".source", Objects.requireNonNull(source, "source is required."));
     }
 
     /**
@@ -69,7 +73,7 @@ public final class PropertyValue {
      * {@link PropertySource#get(String)}.
      */
     public String getValue() {
-        return configEntries.get(key);
+        return this.value;
     }
 
     /**
@@ -77,8 +81,8 @@ public final class PropertyValue {
      * is also used for subsequent processing, like value filtering.
      * @return the property value entry map.
      */
-    public Map<String, String> getConfigEntries() {
-        return Collections.unmodifiableMap(configEntries);
+    public Map<String, String> getMetaEntries() {
+        return Collections.unmodifiableMap(metaEntries);
     }
 
     /**
@@ -111,7 +115,39 @@ public final class PropertyValue {
      * @param key the key, not null.
      * @return the value found, or null.
      */
-    public String get(String key) {
-        return this.configEntries.get(key);
+    public String getMetaEntry(String key) {
+        return this.metaEntries.get(key);
+    }
+
+    /**
+     * Creates a new builder instance based on this item.
+     * @return a new builder, never null.
+     */
+    public PropertyValueBuilder toBuilder() {
+        return new PropertyValueBuilder(this.getKey(), this.getValue(), this.metaEntries);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof PropertyValue)) return false;
+        PropertyValue that = (PropertyValue) o;
+        return Objects.equals(getKey(), that.getKey()) &&
+                Objects.equals(getValue(), that.getValue()) &&
+                Objects.equals(getMetaEntries(), that.getMetaEntries());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getKey(), getValue(), getMetaEntries());
+    }
+
+    @Override
+    public String toString() {
+        return "PropertyValue{" +
+                "key='" + key + '\'' +
+                ", value='" + value + '\'' +
+                ", metaEntries=" + metaEntries +
+                '}';
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/8c0081b9/code/api/src/main/java/org/apache/tamaya/spi/PropertyValueBuilder.java
----------------------------------------------------------------------
diff --git a/code/api/src/main/java/org/apache/tamaya/spi/PropertyValueBuilder.java b/code/api/src/main/java/org/apache/tamaya/spi/PropertyValueBuilder.java
index 7eaeb94..57a40be 100644
--- a/code/api/src/main/java/org/apache/tamaya/spi/PropertyValueBuilder.java
+++ b/code/api/src/main/java/org/apache/tamaya/spi/PropertyValueBuilder.java
@@ -18,6 +18,7 @@
  */
 package org.apache.tamaya.spi;
 
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
@@ -31,7 +32,7 @@ public class PropertyValueBuilder {
     /** The property value. */
     String value;
     /** additional metadata entries (optional). */
-    Map<String,String> contextData = new HashMap<>();
+    Map<String,String> metaEntries = new HashMap<>();
 
     /**
      * Create a new builder instance, for a given set of parameters.
@@ -43,12 +44,25 @@ public class PropertyValueBuilder {
     public PropertyValueBuilder(String key, String value, String source) {
         this.key = Objects.requireNonNull(key);
         this.value = Objects.requireNonNull(value);
-        this.contextData.put("_" + key + ".source", Objects.requireNonNull(source));
+        this.metaEntries.put("source", Objects.requireNonNull(source));
+    }
+
+    /**
+     * Creates a new builder from data from a {@link PropertyValue}.
+     * @param key to access a property value.
+     * @param value the value, not null. If a value is null {@link PropertySource#get(String)} should return
+     * {@code null}.
+     * @param metaEntries the context data, not null.
+     */
+    PropertyValueBuilder(String key, String value, Map<String,String> metaEntries) {
+        this.key = Objects.requireNonNull(key);
+        this.value = Objects.requireNonNull(value);
+        this.metaEntries.putAll(metaEntries);
     }
 
     /**
      * Replaces/sets the context data.
-     * @param contextData the context data to be applied, not null. Note that all keys should only identify the context
+     * @param metaEntries the context data to be applied, not null. Note that all keys should only identify the context
      *                    data item. the builder does create a corresponding metadata entry, e.g.
      *                    <pre>
      *                    provider=myProviderName
@@ -65,11 +79,9 @@ public class PropertyValueBuilder {
      *                    </pre>
      * @return the builder for chaining.
      */
-    public PropertyValueBuilder setContextData(Map<String, String> contextData) {
-        this.contextData.clear();
-        for(Map.Entry<String,String> en:contextData.entrySet()) {
-            this.contextData.put("_"+this.key+'.'+en.getKey(), en.getValue());
-        }
+    public PropertyValueBuilder setMetaEntries(Map<String, String> metaEntries) {
+        this.metaEntries.clear();
+        this.metaEntries.putAll(metaEntries);
         return this;
     }
 
@@ -80,7 +92,44 @@ public class PropertyValueBuilder {
      * @return the builder for chaining.
      */
     public PropertyValueBuilder addContextData(String key, Object value) {
-        this.contextData.put("_"+this.key+'.'+key, String.valueOf(Objects.requireNonNull(value, "Meta value is null.")));
+        this.metaEntries.put(key, String.valueOf(Objects.requireNonNull(value, "Meta value is null.")));
+        return this;
+    }
+
+    /**
+     * Get the value's context data.
+     * @return the context data.
+     */
+    public Map<String,String> getMetaEntries(){
+        return Collections.unmodifiableMap(this.metaEntries);
+    }
+
+    /**
+     * Changes the entry's key, mapping also corresponding context entries.
+     * @param key the new key, not null.
+     * @return the builder for chaining.
+     */
+    public PropertyValueBuilder mapKey(String key) {
+        Map<String,String> newContext = new HashMap<>();
+        for(Map.Entry<String,String> en:this.metaEntries.entrySet()){
+            if(en.getKey().startsWith("_"+this.key)){
+                newContext.put("_"+key+'.'+ en.getKey().substring(this.key.length()+1), en.getValue());
+            }else{
+                newContext.put(en.getKey(), en.getValue());
+            }
+        }
+        this.metaEntries = newContext;
+        this.key = key;
+        return this;
+    }
+
+    /**
+     * Sets a new value.
+     * @param value the new value.
+     * @return the builder for chaining.
+     */
+    public PropertyValueBuilder setValue(String value) {
+        this.value = value;
         return this;
     }
 
@@ -97,7 +146,8 @@ public class PropertyValueBuilder {
         return "PropertyValueBuilder{" +
                 "key='" + key + '\'' +
                 "value='" + value + '\'' +
-                ", contextData=" + contextData +
+                ", metaEntries=" + metaEntries +
                 '}';
     }
+
 }


[5/6] incubator-tamaya git commit: TAMAYA-238: Removed explicit versions.

Posted by an...@apache.org.
TAMAYA-238: Removed explicit versions.


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

Branch: refs/heads/master
Commit: b2dddeb864d16f65c48a151103a96f3eccfa1502
Parents: ae4ebe1
Author: anatole <an...@apache.org>
Authored: Sun Mar 5 21:34:54 2017 +0100
Committer: anatole <an...@apache.org>
Committed: Mon Mar 6 00:29:34 2017 +0100

----------------------------------------------------------------------
 code/api/bnd.bnd  | 3 +--
 code/core/bnd.bnd | 3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b2dddeb8/code/api/bnd.bnd
----------------------------------------------------------------------
diff --git a/code/api/bnd.bnd b/code/api/bnd.bnd
index 4f29bfe..7ca7687 100644
--- a/code/api/bnd.bnd
+++ b/code/api/bnd.bnd
@@ -1,5 +1,4 @@
 Export-Package: \
 	org.apache.tamaya,\
 	org.apache.tamaya.spi
-Bundle-SymbolicName: org.apache.tamaya
-Bundle-Version: 0.3-INCUBATING-SNAPSHOT
\ No newline at end of file
+Bundle-SymbolicName: org.apache.tamaya
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b2dddeb8/code/core/bnd.bnd
----------------------------------------------------------------------
diff --git a/code/core/bnd.bnd b/code/core/bnd.bnd
index 5d14d8c..7aa4182 100644
--- a/code/core/bnd.bnd
+++ b/code/core/bnd.bnd
@@ -8,5 +8,4 @@ Import-Package: \
 	org.osgi.framework,\
 	javax.annotation
 Bundle-Activator: org.apache.tamaya.core.OSGIActivator
-Bundle-SymbolicName: org.apache.tamaya.core
-Bundle-Version: 0.3-INCUBATING-SNAPSHOT
\ No newline at end of file
+Bundle-SymbolicName: org.apache.tamaya.core
\ No newline at end of file


[3/6] incubator-tamaya git commit: TAMAYA-252: Unified PropertyValue API and usage, also separating key, value, source and other meta-data and defining a clear builder policy.

Posted by an...@apache.org.
TAMAYA-252: Unified PropertyValue API and usage, also separating key, value, source and other meta-data and defining a clear builder policy.


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

Branch: refs/heads/master
Commit: ae4ebe1d34a03f7f6e3dd97859533eec879bc639
Parents: 855342a
Author: anatole <an...@apache.org>
Authored: Sun Mar 5 21:27:29 2017 +0100
Committer: anatole <an...@apache.org>
Committed: Mon Mar 6 00:29:34 2017 +0100

----------------------------------------------------------------------
 .../org/apache/tamaya/spi/FilterContext.java    |  20 ++-
 .../org/apache/tamaya/spi/PropertyFilter.java   |   4 +-
 .../org/apache/tamaya/spi/PropertySource.java   |  51 ++++++-
 .../org/apache/tamaya/spi/PropertyValue.java    |  77 +++++++++-
 .../apache/tamaya/spi/PropertyValueBuilder.java |  90 ++++++++----
 .../spi/PropertyValueCombinationPolicy.java     |   7 +-
 .../apache/tamaya/spi/FilterContextTest.java    |  29 ++--
 .../tamaya/spi/PropertyValueBuilderTest.java    | 129 +++++++++++++---
 .../apache/tamaya/spi/PropertyValueTest.java    | 146 ++++++++++++++++++-
 .../core/internal/DefaultConfiguration.java     |  86 +++++------
 .../tamaya/core/internal/PropertyFiltering.java |  33 ++---
 .../core/internal/PropertySourceComparator.java |  88 +++++------
 .../core/internal/WrappedPropertySource.java    |   2 +-
 .../core/propertysource/BasePropertySource.java |  14 +-
 .../core/propertysource/CLIPropertySource.java  |  16 +-
 .../EnvironmentPropertySource.java              |  29 ++--
 .../JavaConfigurationPropertySource.java        |   7 +-
 .../propertysource/SimplePropertySource.java    |  39 ++---
 .../propertysource/SystemPropertySource.java    |  19 +--
 .../core/ConfigurationContextBuilderTest.java   |  27 ++--
 .../apache/tamaya/core/TestPropertySource.java  |   7 +-
 .../DefaultConfigurationContextBuilderTest.java |  19 ++-
 .../DefaultConfigurationContextTest.java        |   2 +-
 .../ConverterTestsPropertySource.java           |   7 +-
 .../propertysource/BasePropertySourceTest.java  |  25 ++--
 .../propertysource/CLIPropertySourceTest.java   |  18 +--
 .../EnvironmentPropertySourceTest.java          |   9 +-
 .../PropertiesFilePropertySourceTest.java       |   6 +-
 .../SimplePropertySourceTest.java               |   5 +-
 .../SystemPropertySourceTest.java               |  28 ++--
 .../provider/JavaConfigurationProviderTest.java |   2 +-
 .../testdata/TestPropertyDefaultSource.java     |   9 +-
 .../core/testdata/TestPropertyFilter.java       |   7 +-
 .../testdata/TestPropertySourceProvider.java    |  13 +-
 .../testdata/TestRemovingPropertyFilter.java    |   7 +-
 .../SimplePropertySource.java                   |   9 +-
 36 files changed, 711 insertions(+), 375 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/api/src/main/java/org/apache/tamaya/spi/FilterContext.java
----------------------------------------------------------------------
diff --git a/code/api/src/main/java/org/apache/tamaya/spi/FilterContext.java b/code/api/src/main/java/org/apache/tamaya/spi/FilterContext.java
index 3c675c8..d5c7850 100644
--- a/code/api/src/main/java/org/apache/tamaya/spi/FilterContext.java
+++ b/code/api/src/main/java/org/apache/tamaya/spi/FilterContext.java
@@ -32,7 +32,7 @@ public class FilterContext {
     /** The key. */
     private final String key;
     @Experimental
-    private Map<String, String> configEntries = new HashMap();
+    private Map<String, PropertyValue> configEntries = new HashMap();
     @Experimental
     private boolean singlePropertyScoped;
 
@@ -40,16 +40,24 @@ public class FilterContext {
     /**
      * Creates a new FilterContext.
      * @param key the key under evaluation, not null.
-     * @param singlePropertyScope true, if the filtering is done only for one single property accessed explcitily.
      * @param configEntries the raw configuration data available in the current evaluation context, not null.
      */
-    public FilterContext(String key, Map<String,String> configEntries, boolean singlePropertyScope) {
-        this.singlePropertyScoped = singlePropertyScope;
+    public FilterContext(String key, Map<String,PropertyValue> configEntries) {
+        this.singlePropertyScoped = false;
         this.key = Objects.requireNonNull(key);
         this.configEntries.putAll(configEntries);
         this.configEntries = Collections.unmodifiableMap(this.configEntries);
     }
 
+    public FilterContext(String key, PropertyValue value) {
+        this.singlePropertyScoped = true;
+        this.key = Objects.requireNonNull(key);
+        if(value!=null) {
+            this.configEntries.put(value.getKey(), value);
+        }
+        this.configEntries = Collections.unmodifiableMap(this.configEntries);
+    }
+
     /**
      * Get the key accessed. This information is very useful to evaluate additional metadata needed to determine/
      * control further aspects of the conversion.
@@ -92,13 +100,13 @@ public class FilterContext {
      * @return the configuration instance, or null.
      */
     @Experimental
-    public Map<String, String> getConfigEntries() {
+    public Map<String, PropertyValue> getConfigEntries() {
         return configEntries;
     }
 
     @Override
     public String toString() {
-        return "FilterContext{key='" + key + "', configEntries=" + configEntries + '}';
+        return "FilterContext{key='" + key + "', configEntries=" + configEntries.keySet() + '}';
     }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
----------------------------------------------------------------------
diff --git a/code/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java b/code/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
index 1ecc88a..c14bd3c 100644
--- a/code/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
+++ b/code/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
@@ -42,7 +42,9 @@ public interface PropertyFilter {
      * @param value the value to be filtered, which also can be {@code null} if removed by another filter.
      * @param context the filter context, not null.
      * @return the filtered value, or {@code null} if the value should be removed alltogether.
+     * @see PropertyValue
+     * @see PropertyValueBuilder
      */
-    String filterProperty(String value, FilterContext context);
+    PropertyValue filterProperty(PropertyValue value, FilterContext context);
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/api/src/main/java/org/apache/tamaya/spi/PropertySource.java
----------------------------------------------------------------------
diff --git a/code/api/src/main/java/org/apache/tamaya/spi/PropertySource.java b/code/api/src/main/java/org/apache/tamaya/spi/PropertySource.java
index 83b2f7a..e0093af 100644
--- a/code/api/src/main/java/org/apache/tamaya/spi/PropertySource.java
+++ b/code/api/src/main/java/org/apache/tamaya/spi/PropertySource.java
@@ -19,6 +19,8 @@
 package org.apache.tamaya.spi;
 
 
+import org.apache.tamaya.Configuration;
+
 import java.util.Collections;
 import java.util.Map;
 
@@ -55,6 +57,7 @@ public interface PropertySource {
      */
     PropertySource EMPTY = new PropertySource() {
 
+        @Override
         public int getOrdinal() {
             return Integer.MIN_VALUE;
         }
@@ -70,7 +73,7 @@ public interface PropertySource {
         }
 
         @Override
-        public Map<String, String> getProperties() {
+        public Map<String, PropertyValue> getProperties() {
             return Collections.emptyMap();
         }
 
@@ -87,6 +90,48 @@ public interface PropertySource {
 
 
     /**
+     * The ordinal value is the default ordering parameter which definines the default order of
+     * auto-discovered property sources. Ordering of property sources is important since values
+     * from property sources with higher ordinal values override values from less significant
+     * property sources.
+     *
+     * By default Tamaya includes the following property sources:
+     * <ol>
+     *     <li>Properties file values (/META-INF/javaconfiguration.properties) (ordinal 100)</li>
+     *     <li>JNDI values (ordinal 200, only when adding the {@code tamaya-jndi} extension module)</li>
+     *     <li>Environment properties (ordinal 300)</li>
+     *     <li>System properties (ordinal 1000)</li>
+     * </ol>
+     *
+     * <p><b>Important Hints for custom implementations</b>:</p>
+     * <p>
+     * If a custom implementation should be invoked <b>before</b> the default implementations, use a value &gt; 1000
+     * </p>
+     * <p>
+     * If a custom implementation should be invoked <b>after</b> the default implementations, use a value &lt; 100
+     * </p>
+     *
+     * <p>Reordering of the default order of the config-sources:</p>
+     * <p>Example: If the properties file/s should be used <b>before</b> the other implementations,
+     * you have to configure an ordinal &gt; 1000. That means, you have to add e.g. tamaya.ordinal=401 to
+     * /META-INF/javaconfiguration.properties . Hint: In case of property files every file is handled as independent
+     * config-source, but all of them have ordinal 400 by default (and can be reordered in a fine-grained manner.</p>
+     *
+     * In cases where it is not possible to change a config sources ordinal value, you may have several options:
+     * <ul>
+     *     <li>you can register an alternate implementation of {@link PropertyValueCombinationPolicy}.</li>
+     *     <li>you can use a {@link ConfigurationContextBuilder} to redefine the source order and finally use
+     *     {@link org.apache.tamaya.ConfigurationProvider#setConfiguration(Configuration)} to
+     *     change the current default {@link Configuration}.</li>
+     *     <li>finally, the imeplementor of this API may define alternate mechanism to reconfigure an ordinal
+     *     in a vendor specific way.</li>
+     * </ul>
+     * @return the 'importance' aka ordinal of the configured values. The higher, the more important.
+     */
+    int getOrdinal();
+
+
+    /**
      * Get the name of the property source. The name should be unique for the type of source, whereas the id is used
      * to ensure unique identity, either locally or remotely.
      * @return the configuration's name, never null.
@@ -103,12 +148,12 @@ public interface PropertySource {
     PropertyValue get(String key);
 
     /**
-     * Access the current properties as Map. The resulting Map may not return all items accessible, e.g.
+     * Access the current properties as Set. The resulting Map may not return all items accessible, e.g.
      * when the underlying storage does not support iteration of its entries.
      *
      * @return the corresponding map, never null.
      */
-    Map<String,String> getProperties();
+    Map<String, PropertyValue> getProperties();
 
     /**
      * Determines if this config source can be scanned for its list of properties.

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/api/src/main/java/org/apache/tamaya/spi/PropertyValue.java
----------------------------------------------------------------------
diff --git a/code/api/src/main/java/org/apache/tamaya/spi/PropertyValue.java b/code/api/src/main/java/org/apache/tamaya/spi/PropertyValue.java
index 0332b85..a622509 100644
--- a/code/api/src/main/java/org/apache/tamaya/spi/PropertyValue.java
+++ b/code/api/src/main/java/org/apache/tamaya/spi/PropertyValue.java
@@ -36,12 +36,15 @@ public final class PropertyValue implements Serializable{
     private String key;
     /** The value. */
     private String value;
+    /** The source of the value. */
+    private String source;
     /** Additional metadata provided by the provider. */
     private Map<String,String> metaEntries = new HashMap<>();
 
     PropertyValue(PropertyValueBuilder builder){
-        this.key = builder.key;
-        this.value = Objects.requireNonNull(builder.value);
+        this.key = Objects.requireNonNull(builder.key);
+        this.value = builder.value;
+        this.source = Objects.requireNonNull(builder.source);
         if(builder.metaEntries !=null) {
             this.metaEntries.putAll(builder.metaEntries);
         }
@@ -56,7 +59,7 @@ public final class PropertyValue implements Serializable{
     private PropertyValue(String key, String value, String source){
         this.key = Objects.requireNonNull(key, "key is required.");
         this.value = Objects.requireNonNull(value);
-        this.metaEntries.put("_"+key+".source", Objects.requireNonNull(source, "source is required."));
+        this.source = Objects.requireNonNull(source);
     }
 
     /**
@@ -68,6 +71,16 @@ public final class PropertyValue implements Serializable{
     }
 
     /**
+     * The source.
+     * @return the source, which provided the value, not null.
+     * @see PropertySource#getName().
+     */
+    public String getSource() {
+        return this.source;
+    }
+
+
+    /**
      * The value.
      * @return the value, in case a value is null it is valid to return {#code null} as result for
      * {@link PropertySource#get(String)}.
@@ -88,7 +101,16 @@ public final class PropertyValue implements Serializable{
     /**
      * Creates a new builder instance.
      * @param key the key, not null.
-     * @param value the value.
+     * @param source the source, typically the name of the {@link PropertySource} providing the value, not null.
+     * @return a new builder instance.
+     */
+    public static PropertyValueBuilder builder(String key, String source){
+        return new PropertyValueBuilder(key, source);
+    }
+
+    /**
+     * Creates a new builder instance.
+     * @param key the key, not null.
      * @param source the source, typically the name of the {@link PropertySource} providing the value, not null.
      * @return a new builder instance.
      */
@@ -96,6 +118,7 @@ public final class PropertyValue implements Serializable{
         return new PropertyValueBuilder(key, value, source);
     }
 
+
     /**
      * Creates a new PropertyValue without any metadata..
      * @param key the key, not null.
@@ -116,7 +139,7 @@ public final class PropertyValue implements Serializable{
      * @return the value found, or null.
      */
     public String getMetaEntry(String key) {
-        return this.metaEntries.get(key);
+        return this.metaEntries.get(Objects.requireNonNull(key));
     }
 
     /**
@@ -124,7 +147,9 @@ public final class PropertyValue implements Serializable{
      * @return a new builder, never null.
      */
     public PropertyValueBuilder toBuilder() {
-        return new PropertyValueBuilder(this.getKey(), this.getValue(), this.metaEntries);
+        return new PropertyValueBuilder(this.getKey(), this.getSource())
+                .setValue(this.getValue())
+        .setMetaEntries(this.metaEntries);
     }
 
     @Override
@@ -134,12 +159,14 @@ public final class PropertyValue implements Serializable{
         PropertyValue that = (PropertyValue) o;
         return Objects.equals(getKey(), that.getKey()) &&
                 Objects.equals(getValue(), that.getValue()) &&
+                Objects.equals(getSource(), that.getSource()) &&
                 Objects.equals(getMetaEntries(), that.getMetaEntries());
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(getKey(), getValue(), getMetaEntries());
+        return Objects.hash(getKey(), getValue(), getSource(),
+                getMetaEntries());
     }
 
     @Override
@@ -147,7 +174,41 @@ public final class PropertyValue implements Serializable{
         return "PropertyValue{" +
                 "key='" + key + '\'' +
                 ", value='" + value + '\'' +
-                ", metaEntries=" + metaEntries +
+                ", source='" + value + '\'' +
+                (metaEntries.isEmpty()?"":", metaEntries=" + metaEntries) +
                 '}';
     }
+
+    /**
+     * Maps a map of {@code Map<String,String>} to a {@code Map<String,PropertyValue>}.
+     * @param config the String based map, not null.
+     * @param source the source name, not null.
+     * @return the corresponding value based map.
+     */
+    public static Map<String,PropertyValue> map(Map<String, String> config, String source) {
+        Map<String,PropertyValue> result = new HashMap<>(config.size());
+        for(Map.Entry<String,String> en:config.entrySet()){
+            result.put(en.getKey(), PropertyValue.of(en.getKey(), en.getValue(), source));
+        }
+        return result;
+    }
+
+    /**
+     * Maps a map of {@code Map<String,String>} to a {@code Map<String,PropertyValue>}.
+     * @param config the String based map, not null.
+     * @param source the source name, not null.
+     * @param metaData additional metadata, not null.
+     * @return the corresponding value based map.
+     */
+    public static Map<String,PropertyValue> map(Map<String, String> config, String source,
+                                                Map<String,String> metaData) {
+        Map<String,PropertyValue> result = new HashMap<>(config.size());
+        for(Map.Entry<String,String> en:config.entrySet()){
+            result.put(en.getKey(),
+                    new PropertyValueBuilder(en.getKey(), source)
+                            .setValue(en.getValue())
+            .addMetaEntries(metaData).build());
+        }
+        return result;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/api/src/main/java/org/apache/tamaya/spi/PropertyValueBuilder.java
----------------------------------------------------------------------
diff --git a/code/api/src/main/java/org/apache/tamaya/spi/PropertyValueBuilder.java b/code/api/src/main/java/org/apache/tamaya/spi/PropertyValueBuilder.java
index 57a40be..6b4f9fd 100644
--- a/code/api/src/main/java/org/apache/tamaya/spi/PropertyValueBuilder.java
+++ b/code/api/src/main/java/org/apache/tamaya/spi/PropertyValueBuilder.java
@@ -31,52 +31,46 @@ public class PropertyValueBuilder {
     String key;
     /** The property value. */
     String value;
+    /** The property vaoue source. */
+    String source;
     /** additional metadata entries (optional). */
     Map<String,String> metaEntries = new HashMap<>();
 
     /**
      * Create a new builder instance, for a given set of parameters.
+     * Before calling build at least a {@link #value} and its {@link #source}
+     * must be set.
+     */
+    PropertyValueBuilder(String key){
+        this.key = Objects.requireNonNull(key);
+    }
+
+    /**
+     * Create a new builder instance, for a given set of parameters.
      * @param key to access a property value.
-     * @param value the value, not null. If a value is null {@link PropertySource#get(String)} should return
-     * {@code null}.
      * @param source property source.
      */
-    public PropertyValueBuilder(String key, String value, String source) {
+    PropertyValueBuilder(String key, String source) {
         this.key = Objects.requireNonNull(key);
-        this.value = Objects.requireNonNull(value);
-        this.metaEntries.put("source", Objects.requireNonNull(source));
+        this.source = Objects.requireNonNull(source);
     }
 
     /**
-     * Creates a new builder from data from a {@link PropertyValue}.
+     * Create a new builder instance, for a given set of parameters.
      * @param key to access a property value.
      * @param value the value, not null. If a value is null {@link PropertySource#get(String)} should return
      * {@code null}.
-     * @param metaEntries the context data, not null.
+     * @param source property source.
      */
-    PropertyValueBuilder(String key, String value, Map<String,String> metaEntries) {
+    PropertyValueBuilder(String key, String value, String source) {
         this.key = Objects.requireNonNull(key);
-        this.value = Objects.requireNonNull(value);
-        this.metaEntries.putAll(metaEntries);
+        this.value = value;
+        this.source = Objects.requireNonNull(source);
     }
 
     /**
      * Replaces/sets the context data.
-     * @param metaEntries the context data to be applied, not null. Note that all keys should only identify the context
-     *                    data item. the builder does create a corresponding metadata entry, e.g.
-     *                    <pre>
-     *                    provider=myProviderName
-     *                    ttl=250
-     *                    creationIndex=1
-     *                    modificationIndex=23
-     *                    </pre>
-     *                    will be mapped, given a key {@code test.env.name} to
-     *                    <pre>
-     *                    _test.env.name.provider=myProviderName
-     *                    _test.env.name.ttl=250
-     *                    _test.env.name.creationIndex=1
-     *                    _test.env.name.modificationIndex=23
-     *                    </pre>
+     * @param metaEntries the context data to be applied, not null.
      * @return the builder for chaining.
      */
     public PropertyValueBuilder setMetaEntries(Map<String, String> metaEntries) {
@@ -91,14 +85,34 @@ public class PropertyValueBuilder {
      * @param value the context value, not null (will be converted to String).
      * @return the builder for chaining.
      */
-    public PropertyValueBuilder addContextData(String key, Object value) {
+    public PropertyValueBuilder addMetaEntry(String key, Object value) {
         this.metaEntries.put(key, String.valueOf(Objects.requireNonNull(value, "Meta value is null.")));
         return this;
     }
 
     /**
+     * Adds the context data given.
+     * @param metaEntries the context data to be applied, not null.
+     * @return the builder for chaining.
+     */
+    public PropertyValueBuilder addMetaEntries(Map<String, String> metaEntries) {
+        this.metaEntries.putAll(metaEntries);
+        return this;
+    }
+
+    /**
+     * Removes a meta entry.
+     * @param key the entry's key, not null.
+     * @return the builder for chaining.
+     */
+    public PropertyValueBuilder removeMetaEntry(String key) {
+        this.metaEntries.remove(key);
+        return this;
+    }
+
+    /**
      * Get the value's context data.
-     * @return the context data.
+     * @return the context data, not null.
      */
     public Map<String,String> getMetaEntries(){
         return Collections.unmodifiableMap(this.metaEntries);
@@ -124,8 +138,18 @@ public class PropertyValueBuilder {
     }
 
     /**
+     * Sets a new key.
+     * @param key the new key, not null.
+     * @return the builder for chaining.
+     */
+    public PropertyValueBuilder setKey(String key) {
+        this.key = Objects.requireNonNull(key);
+        return this;
+    }
+
+    /**
      * Sets a new value.
-     * @param value the new value.
+     * @param value the new value, not null.
      * @return the builder for chaining.
      */
     public PropertyValueBuilder setValue(String value) {
@@ -134,6 +158,16 @@ public class PropertyValueBuilder {
     }
 
     /**
+     * Sets a new source.
+     * @param source the new source, not null.
+     * @return the builder for chaining.
+     */
+    public PropertyValueBuilder setSource(String source) {
+        this.source = Objects.requireNonNull(source);
+        return this;
+    }
+
+    /**
      * Creates a new immutable {@link PropertyValue}.
      * @return a new immutable {@link PropertyValue}, never null.
      */

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/api/src/main/java/org/apache/tamaya/spi/PropertyValueCombinationPolicy.java
----------------------------------------------------------------------
diff --git a/code/api/src/main/java/org/apache/tamaya/spi/PropertyValueCombinationPolicy.java b/code/api/src/main/java/org/apache/tamaya/spi/PropertyValueCombinationPolicy.java
index 096b2a1..81e4b60 100644
--- a/code/api/src/main/java/org/apache/tamaya/spi/PropertyValueCombinationPolicy.java
+++ b/code/api/src/main/java/org/apache/tamaya/spi/PropertyValueCombinationPolicy.java
@@ -18,7 +18,6 @@
  */
 package org.apache.tamaya.spi;
 
-import java.util.Map;
 
 /**
  * Policy that determines how the final value of a configuration entry is evaluated. An instances of this
@@ -36,9 +35,9 @@ public interface PropertyValueCombinationPolicy {
     PropertyValueCombinationPolicy DEFAULT_OVERRIDING_COLLECTOR = new PropertyValueCombinationPolicy(){
 
         @Override
-        public Map<String,String> collect(Map<String,String> currentValue, String key, PropertySource propertySource) {
+        public PropertyValue collect(PropertyValue currentValue, String key, PropertySource propertySource) {
             PropertyValue value = propertySource.get(key);
-            return value!=null?value.getConfigEntries():currentValue;
+            return value!=null?value:currentValue;
         }
 
     };
@@ -61,6 +60,6 @@ public interface PropertyValueCombinationPolicy {
      *                       {@code currentValue} should be returned in almost all cases.
      * @return the value to be used for future evaluation, including metadata entries.
      */
-    Map<String,String> collect(Map<String,String> currentValue, String key, PropertySource propertySource);
+    PropertyValue collect(PropertyValue currentValue, String key, PropertySource propertySource);
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/api/src/test/java/org/apache/tamaya/spi/FilterContextTest.java
----------------------------------------------------------------------
diff --git a/code/api/src/test/java/org/apache/tamaya/spi/FilterContextTest.java b/code/api/src/test/java/org/apache/tamaya/spi/FilterContextTest.java
index 2dcf78a..d8d9380 100644
--- a/code/api/src/test/java/org/apache/tamaya/spi/FilterContextTest.java
+++ b/code/api/src/test/java/org/apache/tamaya/spi/FilterContextTest.java
@@ -32,45 +32,42 @@ public class FilterContextTest {
     @Test
     public void getKey() throws Exception {
         FilterContext ctx = new FilterContext("getKey",
-                new HashMap<String,String>(), true);
+                new HashMap<String,PropertyValue>());
         assertEquals("getKey", ctx.getKey());
     }
 
     @Test
     public void isSinglePropertyScoped() throws Exception {
         FilterContext ctx = new FilterContext("isSinglePropertyScoped",
-                new HashMap<String,String>(), true);
-        assertEquals(true, ctx.isSinglePropertyScoped());
-        ctx = new FilterContext("isSinglePropertyScoped",
-                new HashMap<String,String>(), false);
+                new HashMap<String,PropertyValue>());
         assertEquals(false, ctx.isSinglePropertyScoped());
+        ctx = new FilterContext("isSinglePropertyScoped", PropertyValue.of("isSinglePropertyScoped", "val", "test"));
+        assertEquals(true, ctx.isSinglePropertyScoped());
     }
 
     @Test
     public void getConfigEntries() throws Exception {
-        Map<String,String> config = new HashMap<>();
+        Map<String,PropertyValue> config = new HashMap<>();
         for(int i=0;i<10;i++) {
-            config.put("key-"+i, "value-"+i);
+            config.put("key-"+i, PropertyValue.of("key-"+i, "value-"+i, "test"));
         }
-        FilterContext ctx = new FilterContext("getConfigEntries",
-                config, true);
+        FilterContext ctx = new FilterContext("getMetaEntries", config);
         assertEquals(config, ctx.getConfigEntries());
         assertTrue(config != ctx.getConfigEntries());
     }
 
     @Test
     public void testToString() throws Exception {
-        Map<String,String> config = new HashMap<>();
+        Map<String,PropertyValue> config = new HashMap<>();
         for(int i=0;i<2;i++) {
-            config.put("key-"+i, "value-"+i);
+            config.put("key-"+i, PropertyValue.of("key-"+i, "value-"+i, "test"));
         }
-        FilterContext ctx = new FilterContext("testToString",
-                config, true);
+        FilterContext ctx = new FilterContext("testToString", config);
         String toString = ctx.toString();
         assertNotNull(toString);
-        assertTrue(toString.contains("FilterContext{key='testToString', configEntries={"));
-        assertTrue(toString.contains("key-0=value-0"));
-        assertTrue(toString.contains("key-1=value-1"));
+        assertTrue(toString.contains("FilterContext{key='testToString', configEntries=["));
+        assertTrue(toString.contains("key-0"));
+        assertTrue(toString.contains("key-1"));
         assertTrue(toString.endsWith("}"));
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/api/src/test/java/org/apache/tamaya/spi/PropertyValueBuilderTest.java
----------------------------------------------------------------------
diff --git a/code/api/src/test/java/org/apache/tamaya/spi/PropertyValueBuilderTest.java b/code/api/src/test/java/org/apache/tamaya/spi/PropertyValueBuilderTest.java
index 5fdec2d..75597ea 100644
--- a/code/api/src/test/java/org/apache/tamaya/spi/PropertyValueBuilderTest.java
+++ b/code/api/src/test/java/org/apache/tamaya/spi/PropertyValueBuilderTest.java
@@ -19,6 +19,7 @@
 package org.apache.tamaya.spi;
 
 import org.junit.Test;
+import org.mockito.internal.matchers.Null;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -31,54 +32,142 @@ import static org.junit.Assert.*;
 public class PropertyValueBuilderTest {
 
     @Test
+    public void testCreate1(){
+        new PropertyValueBuilder("k");
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testCreate1_Null(){
+        new PropertyValueBuilder(null);
+    }
+
+    @Test
+    public void testCreate2(){
+        new PropertyValueBuilder("k", "source");
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testCreate2_Null(){
+        new PropertyValueBuilder("k", null);
+    }
+
+    @Test
     public void testKey() throws Exception {
-        PropertyValueBuilder b = new PropertyValueBuilder("k", "v", "testKey");
+        PropertyValueBuilder b = new PropertyValueBuilder("k", "testKey").setValue("v");
         PropertyValue val = b.build();
         assertEquals(val.getKey(),"k");
     }
 
     @Test
+    public void testSource() throws Exception {
+        PropertyValueBuilder b = new PropertyValueBuilder("k", "testSource").setValue("v");
+        PropertyValue val = b.build();
+        assertEquals(val.getSource(),"testSource");
+    }
+
+    @Test
     public void testValue() throws Exception {
-        PropertyValueBuilder b = new PropertyValueBuilder("k", "v", "testValue");
+        PropertyValueBuilder b = new PropertyValueBuilder("k", "testValue").setValue("v");
         PropertyValue val = b.build();
         assertEquals(val.getValue(),"v");
-        assertEquals(val.getConfigEntries().get("k"),"v");
+        assertNull(val.getMetaEntries().get("k"));
     }
 
     @Test(expected=NullPointerException.class)
     public void testKeyNullValue() throws Exception {
-        new PropertyValueBuilder("k", null, "testKeyNullValue");
+        new PropertyValueBuilder(null, "testKeyNullValue");
+    }
+
+    @Test
+    public void testSetMetaEntries() throws Exception {
+        Map<String,String> meta = new HashMap<>();
+        meta.put("1","2");
+        meta.put("a", "b");
+        PropertyValue pv = PropertyValue.builder("k", "testGetKey")
+                .setValue("v")
+                .addMetaEntry("k", "v2")
+                .setMetaEntries(meta).build();
+        assertEquals("v", pv.getValue());
+        assertEquals("k", pv.getKey());
+        assertNull("v2", pv.getMetaEntry("k"));
+        assertEquals("testGetKey", pv.getSource());
+        assertEquals("2", pv.getMetaEntry("1"));
+        assertEquals("b", pv.getMetaEntry("a"));
+    }
+
+    @Test
+    public void testGetKey() throws Exception {
+        PropertyValue pv = PropertyValue.builder("k", "testGetKey").setValue("v").build();
+        assertEquals("k", pv.getKey());
+    }
+
+    @Test
+    public void testGetValue1() throws Exception {
+        PropertyValue pv = PropertyValue.of("k", "v", "testGetValue");
+        assertEquals("v", pv.getValue());
+    }
+
+    @Test
+    public void testGetValue2() throws Exception {
+        PropertyValue pv = PropertyValue.builder("k", "testGetValue").setValue("v").build();
+        assertEquals("v", pv.getValue());
+    }
+
+    @Test
+    public void testRemoveMetaEntry() throws Exception {
+        PropertyValue pv = PropertyValue.builder("k", "testGetKey")
+                .setValue("v")
+                .addMetaEntry("k", "v2")
+                .addMetaEntry("k2", "v22")
+                .removeMetaEntry("k").build();
+        assertEquals("v22", pv.getMetaEntry("k2"));
+        assertNull(pv.getMetaEntry("k"));
+    }
+
+    @Test(expected=NullPointerException.class)
+    public void testSourceNullValue() throws Exception {
+        new PropertyValueBuilder("k", null);
+    }
+
+    @Test
+    public void testGetMetaEntries() throws Exception {
+        Map<String,String> meta = new HashMap<>();
+        meta.put("1","2");
+        meta.put("a", "b");
+        PropertyValue pv = PropertyValue.builder("k", "testGetKey")
+                .setValue("v")
+                .setMetaEntries(meta).build();
+        assertEquals(meta, pv.getMetaEntries());
     }
 
     @Test
     public void testSetContextData() throws Exception {
-        PropertyValueBuilder b = new PropertyValueBuilder("k", "v", "testSetContextData");
+        PropertyValueBuilder b = new PropertyValueBuilder("k", "testSetContextData").setValue("v");
         Map<String,String> context = new HashMap<>();
         context.put("source", "testSetContextData");
         context.put("ts", String.valueOf(System.currentTimeMillis()));
         context.put("y", "yValue");
-        b.setContextData(new HashMap<String, String>());
-        b.setContextData(context);
+        b.setMetaEntries(new HashMap<String, String>());
+        b.setMetaEntries(context);
         context.remove("y");
-        b.setContextData(context);
+        b.setMetaEntries(context);
         PropertyValue contextData = b.build();
-        assertEquals(contextData.getConfigEntries().size(), context.size()+1);
-        assertEquals(contextData.get("_k.source"), "testSetContextData");
-        assertNotNull(contextData.get("_k.ts"));
-        assertNull(contextData.get("_k.y"));
+        assertEquals(contextData.getMetaEntries().size(), context.size());
+        assertEquals(contextData.getMetaEntry("source"), "testSetContextData");
+        assertNotNull(contextData.getMetaEntry("ts"));
+        assertNull(contextData.getMetaEntry("y"));
     }
 
     @Test
     public void testAddContextData() throws Exception {
-        PropertyValueBuilder b = new PropertyValueBuilder("k", "v", "testAddContextData");
-        b.addContextData("ts", System.currentTimeMillis());
-        b.addContextData("y", "yValue");
-        b.addContextData("y", "y2");
+        PropertyValueBuilder b = new PropertyValueBuilder("k", "testAddContextData").setValue("v");
+        b.addMetaEntry("ts", System.currentTimeMillis());
+        b.addMetaEntry("y", "yValue");
+        b.addMetaEntry("y", "y2");
         PropertyValue contextData = b.build();
-        assertEquals(contextData.getConfigEntries().size(), 4);
-        assertEquals(contextData.get("_k.source"), "testAddContextData");
-        assertNotNull(contextData.get("_k.ts"));
-        assertEquals(contextData.get("_k.y"), "y2");
+        assertEquals(contextData.getMetaEntries().size(), 2);
+        assertNotNull(contextData.getMetaEntry("ts"));
+        assertEquals(contextData.getMetaEntry("y"), "y2");
     }
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/api/src/test/java/org/apache/tamaya/spi/PropertyValueTest.java
----------------------------------------------------------------------
diff --git a/code/api/src/test/java/org/apache/tamaya/spi/PropertyValueTest.java b/code/api/src/test/java/org/apache/tamaya/spi/PropertyValueTest.java
index c6909ab..533e978 100644
--- a/code/api/src/test/java/org/apache/tamaya/spi/PropertyValueTest.java
+++ b/code/api/src/test/java/org/apache/tamaya/spi/PropertyValueTest.java
@@ -20,6 +20,9 @@ package org.apache.tamaya.spi;
 
 import org.junit.Test;
 
+import java.util.HashMap;
+import java.util.Map;
+
 import static org.junit.Assert.*;
 
 /**
@@ -28,25 +31,154 @@ import static org.junit.Assert.*;
 public class PropertyValueTest {
 
     @Test
+    public void testOf(){
+        assertNotNull(PropertyValue.of("k", "v", "testGetKey"));
+    }
+
+    @Test
+    public void testHashCode(){
+        assertEquals(PropertyValue.of("k", "v", "testGetKey").hashCode(),
+                PropertyValue.of("k", "v", "testGetKey").hashCode());
+        assertNotSame(PropertyValue.of("k", "v", "testGetKey").hashCode(),
+                PropertyValue.of("k1", "v", "testGetKey").hashCode());
+        assertNotSame(PropertyValue.of("k", "v", "testGetKey").hashCode(),
+                PropertyValue.of("k", "v1", "testGetKey").hashCode());
+        assertNotSame(PropertyValue.of("k", "v", "1").hashCode(),
+                PropertyValue.of("k", "v", "2").hashCode());
+    }
+
+    @Test
+    public void testEquals(){
+        assertEquals(PropertyValue.of("k", "v", "testEquals"),
+                PropertyValue.of("k", "v", "testEquals"));
+        assertNotSame(PropertyValue.of("k2", "v", "testEquals"),
+                PropertyValue.of("k", "v", "testEquals"));
+        assertNotSame(PropertyValue.of("k", "v", "testEquals"),
+                PropertyValue.of("k", "v2", "testEquals"));
+        assertNotSame(PropertyValue.of("k", "v", "testEquals"),
+                PropertyValue.of("k", "v", "testEquals2"));
+    }
+
+    @Test
+    public void testBuilder(){
+        assertNotNull(PropertyValue.builder("k", "testGetKey"));
+        assertEquals(PropertyValue.of("k", "v", "testEquals"),
+                PropertyValue.builder("k", "testEquals").setValue("v").build());
+    }
+
+    @Test
+    public void testToBuilder(){
+        assertNotNull(PropertyValue.of("k", "v", "testGetKey").toBuilder());
+        // round-trip
+        PropertyValue val = PropertyValue.of("k", "v", "testGetKey");
+        assertEquals(val,
+                val.toBuilder().build());
+    }
+
+
+    @Test
     public void testGetKey() throws Exception {
-        PropertyValue pv = PropertyValue.builder("k", "v", "testGetKey").build();
+        PropertyValue pv = PropertyValue.of("k", "v", "testGetKey");
         assertEquals("k", pv.getKey());
     }
 
     @Test
     public void testGetValue() throws Exception {
-        PropertyValue pv = PropertyValue.builder("k", "v", "testGetKey").build();
+        PropertyValue pv = PropertyValue.of("k", "v", "testGetValue");
         assertEquals("v", pv.getValue());
     }
 
     @Test
-    public void testGetContextData() throws Exception {
-        PropertyValue pv = PropertyValue.builder("k", "v", "testGetKey")
-                .addContextData("k", "v2").build();
+    public void testGetSource() throws Exception {
+        PropertyValue pv = PropertyValue.of("k", "v", "testGetSource");
+        assertEquals("testGetSource", pv.getSource());
+        pv = PropertyValue.of("k", "v", "testGetSource");
+        assertEquals("testGetSource", pv.getSource());
+    }
+
+    @Test
+    public void testGetMetaEntry() throws Exception {
+        PropertyValue pv = PropertyValue.builder("k", "testGetMetaEntry").setValue("v")
+                .addMetaEntry("k", "v2").build();
         assertEquals("v", pv.getValue());
         assertEquals("k", pv.getKey());
-        assertEquals("v2", pv.get("_k.k"));
-        assertEquals("testGetKey", pv.get("_k.source"));
+        assertEquals("v2", pv.getMetaEntry("k"));
+        assertEquals("testGetMetaEntry", pv.getSource());
     }
 
+    @Test
+    public void testGetMetaEntries() throws Exception {
+        PropertyValue pv = PropertyValue.of("k", "v", "testGetMetaEntries");
+        assertNotNull(pv.getMetaEntries());
+        assertTrue(pv.getMetaEntries().isEmpty());
+    }
+
+    @Test
+    public void testMap() throws Exception {
+        Map<String,String> map = new HashMap<>();
+        map.put("a", "1");
+        map.put("b", "2");
+        Map<String,PropertyValue> result = PropertyValue.map(map, "source1");
+        assertNotNull(result);
+        assertEquals(map.size(), result.size());
+        for(Map.Entry<String,String>en:map.entrySet()){
+            PropertyValue val = result.get(en.getKey());
+            assertNotNull(val);
+            assertEquals(val.getKey(), en.getKey());
+            assertEquals(val.getValue(), en.getValue());
+            assertEquals(val.getSource(), "source1");
+            assertTrue(val.getMetaEntries().isEmpty());
+        }
+    }
+
+    @Test
+    public void testMapWithMetadata() throws Exception {
+        Map<String,String> map = new HashMap<>();
+        map.put("a", "1");
+        map.put("b", "2");
+        Map<String,String> meta = new HashMap<>();
+        map.put("m1", "n1");
+        map.put("m2", "n2");
+        Map<String,PropertyValue> result = PropertyValue.map(map, "source1", meta);
+        assertNotNull(result);
+        assertEquals(map.size(), result.size());
+        for(Map.Entry<String,String>en:map.entrySet()){
+            PropertyValue val = result.get(en.getKey());
+            assertNotNull(val);
+            assertEquals(val.getKey(), en.getKey());
+            assertEquals(val.getValue(), en.getValue());
+            assertEquals(val.getSource(), "source1");
+            assertEquals(val.getMetaEntries(), meta);
+        }
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testInstantiateNoKey1() throws Exception {
+        PropertyValue pv = PropertyValue.builder(null, "testGetKey").setValue("v").build();
+    }
+    @Test(expected = NullPointerException.class)
+    public void testInstantiateNoKey2() throws Exception {
+        PropertyValue pv = PropertyValue.of(null, "v", "testGetKey");
+    }
+
+    @Test
+    public void testInstantiateNoValue1() throws Exception {
+        PropertyValue pv = PropertyValue.builder("k", "testGetKey").build();
+    }
+    @Test
+    public void testInstantiateNoValue2() throws Exception {
+        PropertyValue pv = PropertyValue.of("k", null, "testGetKey");
+    }
+    @Test(expected = NullPointerException.class)
+    public void testInstantiateNoSource1() throws Exception {
+        PropertyValue pv = PropertyValue.builder("k", null).setValue("v").build();
+    }
+    @Test(expected = NullPointerException.class)
+    public void testInstantiateNoSource2() throws Exception {
+        PropertyValue pv = PropertyValue.of("k", "v", null);
+    }
+    @Test(expected = NullPointerException.class)
+    public void testGetMetaEntry_Null() throws Exception {
+        PropertyValue.of("k", "v", "src").getMetaEntry(null);
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
index 268d825..8ad7489 100644
--- a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
@@ -23,15 +23,8 @@ import org.apache.tamaya.ConfigOperator;
 import org.apache.tamaya.ConfigQuery;
 import org.apache.tamaya.Configuration;
 import org.apache.tamaya.TypeLiteral;
-import org.apache.tamaya.spi.ConfigurationContext;
-import org.apache.tamaya.spi.ConversionContext;
-import org.apache.tamaya.spi.PropertyConverter;
-import org.apache.tamaya.spi.PropertyFilter;
-import org.apache.tamaya.spi.PropertySource;
-import org.apache.tamaya.spi.PropertyValueCombinationPolicy;
-
-import java.util.ArrayList;
-import java.util.Collections;
+import org.apache.tamaya.spi.*;
+
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -55,6 +48,25 @@ public class DefaultConfiguration implements Configuration {
      */
     private final ConfigurationContext configurationContext;
 
+    /**
+     * EvaluationStrategy
+     */
+    private ConfigValueEvaluator configEvaluator = loadConfigValueEvaluator();
+
+    private ConfigValueEvaluator loadConfigValueEvaluator() {
+        ConfigValueEvaluator eval = null;
+        try{
+            eval = ServiceContextManager.getServiceContext()
+                    .getService(ConfigValueEvaluator.class);
+        }catch(Exception e){
+            LOG.log(Level.WARNING, "Failed to load ConfigValueEvaluator from ServiceContext, using default.", e);
+        }
+        if(eval==null){
+            eval = new DefaultConfigValueEvaluator();
+        }
+        return eval;
+    }
+
 
     /**
      * Constructor.
@@ -64,24 +76,17 @@ public class DefaultConfiguration implements Configuration {
         this.configurationContext = Objects.requireNonNull(configurationContext);
     }
 
-
+    @Override
     public String get(String key) {
-        Map<String,String> value = evaluteRawValue(key);
-        if(value==null || value.get(key)==null){
+        PropertyValue value = configEvaluator.evaluteRawValue(key, configurationContext);
+        if(value==null || value.getValue()==null){
             return null;
         }
-        return PropertyFiltering.applyFilter(key, value, configurationContext);
-    }
-
-    protected Map<String,String> evaluteRawValue(String key) {
-        List<PropertySource> propertySources = configurationContext.getPropertySources();
-        Map<String,String> unfilteredValue = null;
-        PropertyValueCombinationPolicy combinationPolicy = this.configurationContext
-                .getPropertyValueCombinationPolicy();
-        for (PropertySource propertySource : propertySources) {
-            unfilteredValue = combinationPolicy.collect(unfilteredValue, key, propertySource);
+        value = PropertyFiltering.applyFilter(key, value, configurationContext);
+        if(value!=null){
+            return value.getValue();
         }
-        return unfilteredValue;
+        return null;
     }
 
 
@@ -111,28 +116,21 @@ public class DefaultConfiguration implements Configuration {
      */
     @Override
     public Map<String, String> getProperties() {
-        return PropertyFiltering.applyFilters(evaluateUnfilteredMap(), configurationContext);
-    }
-
-    protected Map<String, String> evaluateUnfilteredMap() {
-        List<PropertySource> propertySources = new ArrayList<>(configurationContext.getPropertySources());
-        Collections.reverse(propertySources);
-        Map<String, String> result = new HashMap<>();
-        for (PropertySource propertySource : propertySources) {
-            try {
-                int origSize = result.size();
-                Map<String, String> otherMap = propertySource.getProperties();
-                LOG.log(Level.FINEST, null, "Overriding with properties from " + propertySource.getName());
-                result.putAll(otherMap);
-                LOG.log(Level.FINEST, null, "Handled properties from " + propertySource.getName() + "(new: " +
-                        (result.size() - origSize) + ", overrides: " + origSize + ", total: " + result.size());
-            } catch (Exception e) {
-                LOG.log(Level.SEVERE, "Error adding properties from PropertySource: " + propertySource + ", ignoring PropertySource.", e);
+        Map<String, PropertyValue> filtered = PropertyFiltering.applyFilters(
+                configEvaluator.evaluateRawValues(configurationContext),
+                configurationContext);
+        Map<String,String> result = new HashMap<>();
+        for(PropertyValue val:filtered.values()){
+            if(val.getValue()!=null) {
+                result.put(val.getKey(), val.getValue());
+                // TODO: Discuss metadata handling...
+                result.putAll(val.getMetaEntries());
             }
         }
         return result;
     }
 
+
     /**
      * Accesses the current String value for the given key and tries to convert it
      * using the {@link PropertyConverter} instances provided by the current
@@ -215,14 +213,6 @@ public class DefaultConfiguration implements Configuration {
         return this.configurationContext;
     }
 
-    /**
-     * Access the configuration's context.
-     * @return the configurastion context-
-     */
-    public ConfigurationContext getConfigurationContext() {
-        return configurationContext;
-    }
-
     @Override
     public String toString() {
         return "Configuration{\n " +

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyFiltering.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyFiltering.java b/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyFiltering.java
index 1872be4..932d38c 100644
--- a/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyFiltering.java
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyFiltering.java
@@ -22,6 +22,7 @@ import org.apache.tamaya.spi.ConfigurationContext;
 import org.apache.tamaya.spi.FilterContext;
 import org.apache.tamaya.spi.PropertyFilter;
 import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
 
 import java.util.Collections;
 import java.util.HashMap;
@@ -51,27 +52,26 @@ public final class PropertyFiltering{
      */
     private PropertyFiltering(){}
 
-    public static String applyFilter(String key, Map<String,String> configData, ConfigurationContext configurationContext) {
+    public static PropertyValue applyFilter(String key, PropertyValue value, ConfigurationContext configurationContext) {
         // Apply filters to values, prevent values filtered to null!
-        String result = configData.get(key);
         for (int i = 0; i < MAX_FILTER_LOOPS; i++) {
             boolean changed = false;
             // Apply filters to values, prevent values filtered to null!
-            FilterContext filterContext = new FilterContext(key, configData, true);
+            FilterContext filterContext = new FilterContext(key, value);
             for (PropertyFilter filter : configurationContext.getPropertyFilters()) {
-                String newValue = filter.filterProperty(result, filterContext);
-                if (newValue != null && !newValue.equals(result)) {
+                PropertyValue newValue = filter.filterProperty(value, filterContext);
+                if (newValue != null && !newValue.equals(value)) {
                     changed = true;
                     if (LOG.isLoggable(Level.FINEST)) {
-                        LOG.finest("Filter - " + key + ": " + result + " -> " + newValue + " by " + filter);
+                        LOG.finest("Filter - " + value + " -> " + newValue + " by " + filter);
                     }
-                } else if (result != null && !result.equals(newValue)) {
+                } else if (value != null && !value.equals(newValue)) {
                     changed = true;
                     if (LOG.isLoggable(Level.FINEST)) {
-                        LOG.finest("Filter - " + key + ": " + result + " -> " + newValue + " by " + filter);
+                        LOG.finest("Filter - " + value + " -> " + newValue + " by " + filter);
                     }
                 }
-                result = newValue;
+                value = newValue;
             }
             if (!changed) {
                 LOG.finest("Finishing filter loop, no changes detected.");
@@ -86,21 +86,20 @@ public final class PropertyFiltering{
                 }
             }
         }
-        return result;
+        return value;
     }
 
-    public static Map<String, String> applyFilters(Map<String, String> inputMap, ConfigurationContext configurationContext) {
-        Map<String, String> resultMap = new HashMap<>(inputMap);
+    public static Map<String, PropertyValue> applyFilters(Map<String, PropertyValue> inputMap, ConfigurationContext configurationContext) {
+        Map<String, PropertyValue> resultMap = new HashMap<>(inputMap);
         // Apply filters to values, prevent values filtered to null!
-        Map<String, String> metaData = filterMetadata(inputMap);
         for (int i = 0; i < MAX_FILTER_LOOPS; i++) {
             AtomicInteger changes = new AtomicInteger();
-            for (Map.Entry<String, String> entry : inputMap.entrySet()) {
-                FilterContext filterContext = new FilterContext(entry.getKey(), inputMap, false);
+            for (Map.Entry<String, PropertyValue> entry : inputMap.entrySet()) {
+                FilterContext filterContext = new FilterContext(entry.getKey(), inputMap);
                 for (PropertyFilter filter : configurationContext.getPropertyFilters()) {
                     final String k = entry.getKey();
-                    final String v = entry.getValue();
-                    String newValue = filter.filterProperty(v, filterContext);
+                    final PropertyValue v = entry.getValue();
+                    PropertyValue newValue = filter.filterProperty(v, filterContext);
                     if (newValue != null && !newValue.equals(v)) {
                         changes.incrementAndGet();
                         LOG.finest("Filter - " + k + ": " + v + " -> " + newValue + " by " + filter);

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/main/java/org/apache/tamaya/core/internal/PropertySourceComparator.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/PropertySourceComparator.java b/code/core/src/main/java/org/apache/tamaya/core/internal/PropertySourceComparator.java
index 2793f1f..7e9c503 100644
--- a/code/core/src/main/java/org/apache/tamaya/core/internal/PropertySourceComparator.java
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/PropertySourceComparator.java
@@ -85,50 +85,50 @@ public class PropertySourceComparator implements Comparator<PropertySource>, Ser
      * @return the ordinal value to compare the property source.
      */
     public static int getOrdinal(PropertySource propertySource) {
-        PropertyValue ordinalValue = propertySource.get(PropertySource.TAMAYA_ORDINAL);
-        if(ordinalValue!=null){
-            try{
-                return Integer.parseInt(ordinalValue.getValue().trim());
-            }catch(Exception e){
-                LOG.finest("Failed to parse ordinal from " + PropertySource.TAMAYA_ORDINAL +
-                        " in " + propertySource.getName()+": "+ordinalValue.getValue());
-            }
-        }
-        try {
-            Method method = propertySource.getClass().getMethod("getOrdinal");
-            if(int.class.equals(method.getReturnType())){
-                if(!method.isAccessible()){
-                    method.setAccessible(true);
-                }
-                try {
-                    return (int)method.invoke(propertySource);
-                } catch (Exception e) {
-                    LOG.log(Level.FINEST, "Error calling 'int getOrdinal()' on " + propertySource.getName(), e);
-                }
-            }
-        } catch (NoSuchMethodException e) {
-            LOG.finest("No 'int getOrdinal()' method found in " + propertySource.getName());
-        }
-        try {
-            Field field = propertySource.getClass().getField("ORDINAL");
-            if(int.class.equals(field.getType()) && Modifier.isStatic(field.getModifiers())){
-                if(!field.isAccessible()){
-                    field.setAccessible(true);
-                }
-                try {
-                    return (int)field.get(propertySource);
-                } catch (Exception e) {
-                    LOG.log(Level.FINEST, "Error evaluating 'int ORDINAL' on " + propertySource.getName(), e);
-                }
-            }
-        } catch (NoSuchFieldException e) {
-            LOG.finest("No 'int ORDINAL' field found in " + propertySource.getName());
-        }
-        Priority prio = propertySource.getClass().getAnnotation(Priority.class);
-        if(prio!=null){
-            return prio.value();
-        }
-        return 0;
+//        PropertyValue ordinalValue = propertySource.get(PropertySource.TAMAYA_ORDINAL);
+//        if(ordinalValue!=null){
+//            try{
+//                return Integer.parseInt(ordinalValue.getValue().trim());
+//            }catch(Exception e){
+//                LOG.finest("Failed to parse ordinal from " + PropertySource.TAMAYA_ORDINAL +
+//                        " in " + propertySource.getName()+": "+ordinalValue.getValue());
+//            }
+//        }
+//        try {
+//            Method method = propertySource.getClass().getMethod("getOrdinal");
+//            if(int.class.equals(method.getReturnType())){
+//                if(!method.isAccessible()){
+//                    method.setAccessible(true);
+//                }
+//                try {
+//                    return (int)method.invoke(propertySource);
+//                } catch (Exception e) {
+//                    LOG.log(Level.FINEST, "Error calling 'int getOrdinal()' on " + propertySource.getName(), e);
+//                }
+//            }
+//        } catch (NoSuchMethodException e) {
+//            LOG.finest("No 'int getOrdinal()' method found in " + propertySource.getName());
+//        }
+//        try {
+//            Field field = propertySource.getClass().getField("ORDINAL");
+//            if(int.class.equals(field.getType()) && Modifier.isStatic(field.getModifiers())){
+//                if(!field.isAccessible()){
+//                    field.setAccessible(true);
+//                }
+//                try {
+//                    return (int)field.get(propertySource);
+//                } catch (Exception e) {
+//                    LOG.log(Level.FINEST, "Error evaluating 'int ORDINAL' on " + propertySource.getName(), e);
+//                }
+//            }
+//        } catch (NoSuchFieldException e) {
+//            LOG.finest("No 'int ORDINAL' field found in " + propertySource.getName());
+//        }
+//        Priority prio = propertySource.getClass().getAnnotation(Priority.class);
+//        if(prio!=null){
+//            return prio.value();
+//        }
+        return propertySource.getOrdinal();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/main/java/org/apache/tamaya/core/internal/WrappedPropertySource.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/WrappedPropertySource.java b/code/core/src/main/java/org/apache/tamaya/core/internal/WrappedPropertySource.java
index db1a911..32bb12b 100644
--- a/code/core/src/main/java/org/apache/tamaya/core/internal/WrappedPropertySource.java
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/WrappedPropertySource.java
@@ -84,7 +84,7 @@ class WrappedPropertySource implements PropertySource{
     }
 
     @Override
-    public Map<String, String> getProperties() {
+    public Map<String, PropertyValue> getProperties() {
         return delegate.getProperties();
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/main/java/org/apache/tamaya/core/propertysource/BasePropertySource.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/propertysource/BasePropertySource.java b/code/core/src/main/java/org/apache/tamaya/core/propertysource/BasePropertySource.java
index 5a41848..ebc681a 100644
--- a/code/core/src/main/java/org/apache/tamaya/core/propertysource/BasePropertySource.java
+++ b/code/core/src/main/java/org/apache/tamaya/core/propertysource/BasePropertySource.java
@@ -20,7 +20,6 @@ package org.apache.tamaya.core.propertysource;
 
 import org.apache.tamaya.spi.PropertySource;
 import org.apache.tamaya.spi.PropertyValue;
-import org.apache.tamaya.spi.PropertyValueBuilder;
 
 import java.util.Map;
 import java.util.Objects;
@@ -135,19 +134,12 @@ public abstract class BasePropertySource implements PropertySource {
 
     @Override
     public PropertyValue get(String key) {
-        Map<String,String> properties = getProperties();
-        String val = properties.get(key);
+        Map<String,PropertyValue> properties = getProperties();
+        PropertyValue val = properties.get(key);
         if(val==null){
             return null;
         }
-        PropertyValueBuilder b = new PropertyValueBuilder(key, val, getName());
-        String metaKeyStart = "_" + key + ".";
-        for(Map.Entry<String,String> en:properties.entrySet()) {
-            if(en.getKey().startsWith(metaKeyStart) && en.getValue()!=null){
-                b.addContextData(en.getKey().substring(metaKeyStart.length()), en.getValue());
-            }
-        }
-        return b.build();
+        return val;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/main/java/org/apache/tamaya/core/propertysource/CLIPropertySource.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/propertysource/CLIPropertySource.java b/code/core/src/main/java/org/apache/tamaya/core/propertysource/CLIPropertySource.java
index 12e4932..6f2489d 100644
--- a/code/core/src/main/java/org/apache/tamaya/core/propertysource/CLIPropertySource.java
+++ b/code/core/src/main/java/org/apache/tamaya/core/propertysource/CLIPropertySource.java
@@ -18,6 +18,8 @@
  */
 package org.apache.tamaya.core.propertysource;
 
+import org.apache.tamaya.spi.PropertyValue;
+
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
@@ -33,7 +35,7 @@ public class CLIPropertySource extends BasePropertySource{
     private static String[] args = new String[0];
 
     /** The map of parsed main arguments. */
-    private static Map<String,String> mainArgs;
+    private static Map<String,PropertyValue> mainArgs;
 
     /* Initializes the initial state. */
     static {
@@ -83,7 +85,7 @@ public class CLIPropertySource extends BasePropertySource{
         if(argsProp!=null){
             CLIPropertySource.args = argsProp.split("\\s");
         }
-        Map<String,String> result = null;
+        Map<String,PropertyValue> result;
         if(CLIPropertySource.args==null){
             result = Collections.emptyMap();
         }else{
@@ -99,19 +101,19 @@ public class CLIPropertySource extends BasePropertySource{
                     int index = arg.indexOf("=");
                     if(index>0){
                         key = arg.substring(0,index).trim();
-                        result.put(prefix+key, arg.substring(index+1).trim());
+                        result.put(prefix+key, PropertyValue.of(key, arg.substring(index+1).trim(), "main-args"));
                         key = null;
                     }else{
-                        result.put(prefix+arg, arg);
+                        result.put(prefix+arg, PropertyValue.of(prefix+arg, arg, "main-args"));
                     }
                 }else if(arg.startsWith("-")){
                     key = arg.substring(1);
                 }else{
                     if(key!=null){
-                        result.put(prefix+key, arg);
+                        result.put(prefix+key, PropertyValue.of(prefix+key, arg, "main-args"));
                         key = null;
                     }else{
-                        result.put(prefix+arg, arg);
+                        result.put(prefix+arg, PropertyValue.of(prefix+arg, arg, "main-args"));
                     }
                 }
             }
@@ -120,7 +122,7 @@ public class CLIPropertySource extends BasePropertySource{
     }
 
     @Override
-    public Map<String, String> getProperties() {
+    public Map<String, PropertyValue> getProperties() {
         return Collections.unmodifiableMap(mainArgs);
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/main/java/org/apache/tamaya/core/propertysource/EnvironmentPropertySource.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/propertysource/EnvironmentPropertySource.java b/code/core/src/main/java/org/apache/tamaya/core/propertysource/EnvironmentPropertySource.java
index 3bab3b2..c204d26 100644
--- a/code/core/src/main/java/org/apache/tamaya/core/propertysource/EnvironmentPropertySource.java
+++ b/code/core/src/main/java/org/apache/tamaya/core/propertysource/EnvironmentPropertySource.java
@@ -20,10 +20,7 @@ package org.apache.tamaya.core.propertysource;
 
 import org.apache.tamaya.spi.PropertyValue;
 
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.logging.Logger;
+import java.util.*;
 
 /**
  * This {@link org.apache.tamaya.spi.PropertySource} provides all properties which are set
@@ -34,8 +31,6 @@ import java.util.logging.Logger;
  */
 public class EnvironmentPropertySource extends BasePropertySource {
 
-    private static final Logger LOG = Logger.getLogger(EnvironmentPropertySource.class.getName());
-
     /**
      * Default ordinal for {@link org.apache.tamaya.core.propertysource.EnvironmentPropertySource}
      */
@@ -146,25 +141,21 @@ public class EnvironmentPropertySource extends BasePropertySource {
     }
 
     @Override
-    public Map<String, String> getProperties() {
+    public Map<String, PropertyValue> getProperties() {
         if(disabled){
             return Collections.emptyMap();
         }
         String prefix = this.prefix;
-        if(prefix==null) {
-            Map<String, String> entries = new HashMap<>(System.getenv());
-            for (Map.Entry<String, String> entry : System.getenv().entrySet()) {
-                entries.put("_" + entry.getKey() + ".source", getName());
-            }
-            return entries;
-        }else{
-            Map<String, String> entries = new HashMap<>();
-            for (Map.Entry<String, String> entry : System.getenv().entrySet()) {
-                entries.put(prefix + entry.getKey(), entry.getValue());
-                entries.put("_" + prefix + entry.getKey() + ".source", getName());
+        Map<String,String> envProps = System.getenv();
+        Map<String, PropertyValue> values = new HashMap<>();
+        for (Map.Entry<String,String> entry : envProps.entrySet()) {
+            if(prefix==null) {
+                values.put(entry.getKey(), PropertyValue.of(entry.getKey(), entry.getValue(), getName()));
+            }else {
+                values.put(prefix + entry.getKey(), PropertyValue.of(prefix + entry.getKey(), entry.getValue(), getName()));
             }
-            return entries;
         }
+        return values;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/main/java/org/apache/tamaya/core/propertysource/JavaConfigurationPropertySource.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/propertysource/JavaConfigurationPropertySource.java b/code/core/src/main/java/org/apache/tamaya/core/propertysource/JavaConfigurationPropertySource.java
index 90abb72..a6cd5e3 100644
--- a/code/core/src/main/java/org/apache/tamaya/core/propertysource/JavaConfigurationPropertySource.java
+++ b/code/core/src/main/java/org/apache/tamaya/core/propertysource/JavaConfigurationPropertySource.java
@@ -20,9 +20,8 @@ package org.apache.tamaya.core.propertysource;
 
 import org.apache.tamaya.ConfigException;
 import org.apache.tamaya.core.internal.PropertySourceComparator;
-import org.apache.tamaya.core.propertysource.SimplePropertySource;
 import org.apache.tamaya.spi.PropertySource;
-import org.apache.tamaya.spi.PropertySourceProvider;
+import org.apache.tamaya.spi.PropertyValue;
 import org.apache.tamaya.spi.ServiceContextManager;
 
 import java.io.IOException;
@@ -115,11 +114,11 @@ public class JavaConfigurationPropertySource extends BasePropertySource {
 
 
     @Override
-    public Map<String, String> getProperties() {
+    public Map<String, PropertyValue> getProperties() {
         if (!isEnabled()) {
             return Collections.emptyMap();
         }
-        Map<String,String> result = new HashMap<>();
+        Map<String,PropertyValue> result = new HashMap<>();
         for(PropertySource ps:getPropertySources()){
             result.putAll(ps.getProperties());
         }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/main/java/org/apache/tamaya/core/propertysource/SimplePropertySource.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/propertysource/SimplePropertySource.java b/code/core/src/main/java/org/apache/tamaya/core/propertysource/SimplePropertySource.java
index 6a06b62..2c8ec0b 100644
--- a/code/core/src/main/java/org/apache/tamaya/core/propertysource/SimplePropertySource.java
+++ b/code/core/src/main/java/org/apache/tamaya/core/propertysource/SimplePropertySource.java
@@ -19,6 +19,7 @@
 package org.apache.tamaya.core.propertysource;
 
 import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.spi.PropertyValue;
 
 import java.io.File;
 import java.io.IOException;
@@ -39,14 +40,9 @@ public class SimplePropertySource extends BasePropertySource {
     private static final Logger LOG = Logger.getLogger(SimplePropertySource.class.getName());
 
     /**
-     * The property source name.
-     */
-    private String name;
-
-    /**
      * The current properties.
      */
-    private Map<String, String> properties;
+    private Map<String, PropertyValue> properties = new HashMap<>();
 
     /**
      * Creates a new Properties based PropertySource based on the given URL.
@@ -56,7 +52,7 @@ public class SimplePropertySource extends BasePropertySource {
     public SimplePropertySource(File propertiesLocation) {
         super(0);
         try {
-            this.name = propertiesLocation.toString();
+            setName(propertiesLocation.toString());
             this.properties = load(propertiesLocation.toURI().toURL());
         } catch (IOException e) {
             throw new ConfigException("Failed to load properties from " + propertiesLocation, e);
@@ -71,7 +67,7 @@ public class SimplePropertySource extends BasePropertySource {
     public SimplePropertySource(URL propertiesLocation) {
         super(0);
         this.properties = load(Objects.requireNonNull(propertiesLocation));
-        this.name = propertiesLocation.toString();
+        setName(propertiesLocation.toString());
     }
 
     /**
@@ -82,8 +78,10 @@ public class SimplePropertySource extends BasePropertySource {
      */
     public SimplePropertySource(String name, Map<String, String> properties) {
         super(0);
-        this.properties = new HashMap<>(properties);
-        this.name = Objects.requireNonNull(name);
+        setName(Objects.requireNonNull(name));
+        for(Map.Entry<String,String> en:properties.entrySet()){
+            this.properties.put(en.getKey(), PropertyValue.of(en.getKey(), en.getValue(), name));
+        }
     }
 
     /**
@@ -95,16 +93,11 @@ public class SimplePropertySource extends BasePropertySource {
     public SimplePropertySource(String name, URL propertiesLocation) {
         super(0);
         this.properties = load(propertiesLocation);
-        this.name = Objects.requireNonNull(name);
+        setName(name);
     }
 
     @Override
-    public String getName() {
-        return name;
-    }
-
-    @Override
-    public Map<String, String> getProperties() {
+    public Map<String, PropertyValue> getProperties() {
         return this.properties;
     }
 
@@ -115,10 +108,11 @@ public class SimplePropertySource extends BasePropertySource {
      * @return loaded {@link java.util.Properties}
      * @throws IllegalStateException in case of an error while reading properties-file
      */
-    private Map<String, String> load(URL propertiesFile) {
+    private Map<String, PropertyValue> load(URL propertiesFile) {
+        setName(propertiesFile.toString());
         boolean isXML = isXMLPropertieFiles(propertiesFile);
 
-        Map<String, String> properties = new HashMap<>();
+        Map<String, PropertyValue> properties = new HashMap<>();
         try (InputStream stream = propertiesFile.openStream()) {
             Properties props = new Properties();
             if (stream != null) {
@@ -130,12 +124,7 @@ public class SimplePropertySource extends BasePropertySource {
             }
 
             for (String key : props.stringPropertyNames()) {
-                properties.put(key, props.getProperty(key));
-                if (getName() == null){
-                    LOG.finest("No property source name found for " + this +", ommitting source meta-entries.");
-                } else {
-                    properties.put("_" + key + ".source", getName());
-                }
+                properties.put(key, PropertyValue.of(key, props.getProperty(key), getName()));
             }
         } catch (IOException e) {
             throw new ConfigException("Error loading properties from " + propertiesFile, e);

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/main/java/org/apache/tamaya/core/propertysource/SystemPropertySource.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/propertysource/SystemPropertySource.java b/code/core/src/main/java/org/apache/tamaya/core/propertysource/SystemPropertySource.java
index 5c7604e..4dca29d 100644
--- a/code/core/src/main/java/org/apache/tamaya/core/propertysource/SystemPropertySource.java
+++ b/code/core/src/main/java/org/apache/tamaya/core/propertysource/SystemPropertySource.java
@@ -36,7 +36,7 @@ public class SystemPropertySource extends BasePropertySource {
      */
     public static final int DEFAULT_ORDINAL = 1000;
 
-    private volatile Map<String,String> cachedProperties;
+    private volatile Map<String, PropertyValue> cachedProperties;
 
     /**
      * previous System.getProperties().hashCode()
@@ -131,21 +131,19 @@ public class SystemPropertySource extends BasePropertySource {
     }
 
 
-    private Map<String, String> loadProperties() {
+    private Map<String,PropertyValue> loadProperties() {
         Properties sysProps = System.getProperties();
         previousHash = System.getProperties().hashCode();
         final String prefix = this.prefix;
-        Map<String, String> entries = new HashMap<>();
+        Map<String,PropertyValue> values = new HashMap<>();
         for (Map.Entry<Object,Object> entry : sysProps.entrySet()) {
             if(prefix==null) {
-                entries.put("_" + entry.getKey() + ".source", getName());
-                entries.put((String) entry.getKey(), (String) entry.getValue());
+                values.put((String) entry.getKey(), PropertyValue.of((String) entry.getKey(), (String)entry.getValue(), getName()));
             }else {
-                entries.put(prefix + entry.getKey(), (String)entry.getValue());
-                entries.put("_" + prefix + entry.getKey() + ".source", getName());
+                values.put(prefix + entry.getKey(), PropertyValue.of(prefix + entry.getKey(), (String)entry.getValue(), getName()));
             }
         }
-        return entries;
+        return values;
     }
 
     @Override
@@ -169,7 +167,7 @@ public class SystemPropertySource extends BasePropertySource {
     }
 
     @Override
-    public Map<String, String> getProperties() {
+    public Map<String, PropertyValue> getProperties() {
         if(disabled){
             return Collections.emptyMap();
         }
@@ -177,8 +175,7 @@ public class SystemPropertySource extends BasePropertySource {
         // synchronization was removed, Instance was marked as volatile. In the worst case it
         // is reloaded twice, but the values will be the same.
         if (previousHash != System.getProperties().hashCode()) {
-            Map<String, String> properties = loadProperties();
-            this.cachedProperties = Collections.unmodifiableMap(properties);
+            this.cachedProperties = Collections.unmodifiableMap(loadProperties());
         }
         return this.cachedProperties;
     }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/test/java/org/apache/tamaya/core/ConfigurationContextBuilderTest.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/ConfigurationContextBuilderTest.java b/code/core/src/test/java/org/apache/tamaya/core/ConfigurationContextBuilderTest.java
index 9a1dd6f..f1e8ea4 100644
--- a/code/core/src/test/java/org/apache/tamaya/core/ConfigurationContextBuilderTest.java
+++ b/code/core/src/test/java/org/apache/tamaya/core/ConfigurationContextBuilderTest.java
@@ -130,13 +130,13 @@ public class ConfigurationContextBuilderTest {
     public void addPropertyFilters_Array() throws Exception {
         PropertyFilter filter1 = new PropertyFilter(){
             @Override
-            public String filterProperty(String value, FilterContext context) {
+            public PropertyValue filterProperty(PropertyValue value, FilterContext context) {
                 return value;
             }
         };
         PropertyFilter filter2 = new PropertyFilter(){
             @Override
-            public String filterProperty(String value, FilterContext context) {
+            public PropertyValue filterProperty(PropertyValue value, FilterContext context) {
                 return value;
             }
         };
@@ -156,13 +156,13 @@ public class ConfigurationContextBuilderTest {
     public void addPropertyFilters_Collection() throws Exception {
         PropertyFilter filter1 = new PropertyFilter(){
             @Override
-            public String filterProperty(String value, FilterContext context) {
+            public PropertyValue filterProperty(PropertyValue value, FilterContext context) {
                 return value;
             }
         };
         PropertyFilter filter2 = new PropertyFilter(){
             @Override
-            public String filterProperty(String value, FilterContext context) {
+            public PropertyValue filterProperty(PropertyValue value, FilterContext context) {
                 return value;
             }
         };
@@ -182,13 +182,13 @@ public class ConfigurationContextBuilderTest {
     public void removePropertyFilters_Array() throws Exception {
         PropertyFilter filter1 = new PropertyFilter(){
             @Override
-            public String filterProperty(String value, FilterContext context) {
+            public PropertyValue filterProperty(PropertyValue value, FilterContext context) {
                 return value;
             }
         };
         PropertyFilter filter2 = new PropertyFilter(){
             @Override
-            public String filterProperty(String value, FilterContext context) {
+            public PropertyValue filterProperty(PropertyValue value, FilterContext context) {
                 return value;
             }
         };
@@ -211,13 +211,13 @@ public class ConfigurationContextBuilderTest {
     public void removePropertyFilters_Collection() throws Exception {
         PropertyFilter filter1 = new PropertyFilter(){
             @Override
-            public String filterProperty(String value, FilterContext context) {
+            public PropertyValue filterProperty(PropertyValue value, FilterContext context) {
                 return value;
             }
         };
         PropertyFilter filter2 = new PropertyFilter(){
             @Override
-            public String filterProperty(String value, FilterContext context) {
+            public PropertyValue filterProperty(PropertyValue value, FilterContext context) {
                 return value;
             }
         };
@@ -326,9 +326,8 @@ public class ConfigurationContextBuilderTest {
     @Test
     public void setPropertyValueCombinationPolicy() throws Exception {
         PropertyValueCombinationPolicy combPol = new PropertyValueCombinationPolicy(){
-
             @Override
-            public Map<String, String> collect(Map<String, String> currentValue, String key, PropertySource propertySource) {
+            public PropertyValue collect(PropertyValue currentValue, String key, PropertySource propertySource) {
                 return currentValue;
             }
         };
@@ -457,8 +456,8 @@ public class ConfigurationContextBuilderTest {
         for(int i=0;i<propertyFilters.length;i++){
             propertyFilters[i] = new PropertyFilter(){
                 @Override
-                public String filterProperty(String value, FilterContext context) {
-                    return toString() + " - ";
+                public PropertyValue filterProperty(PropertyValue value, FilterContext context) {
+                    return value.toBuilder().setValue(toString() + " - ").build();
                 }
             };
         }
@@ -491,8 +490,8 @@ public class ConfigurationContextBuilderTest {
         ConfigurationContextBuilder b = ConfigurationProvider.getConfigurationContextBuilder();
         b.addPropertyFilters(new PropertyFilter(){
             @Override
-            public String filterProperty(String value, FilterContext context) {
-                return toString() + " - ";
+            public PropertyValue filterProperty(PropertyValue value, FilterContext context) {
+                return value.toBuilder().setValue(toString() + " - ").build();
             }
         });
         assertFalse(b.getPropertyFilters().isEmpty());

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/test/java/org/apache/tamaya/core/TestPropertySource.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/TestPropertySource.java b/code/core/src/test/java/org/apache/tamaya/core/TestPropertySource.java
index 50e26e4..91d83d2 100644
--- a/code/core/src/test/java/org/apache/tamaya/core/TestPropertySource.java
+++ b/code/core/src/test/java/org/apache/tamaya/core/TestPropertySource.java
@@ -21,6 +21,7 @@ package org.apache.tamaya.core;
 
 import org.apache.tamaya.spi.PropertySource;
 import org.apache.tamaya.spi.PropertyValue;
+import org.apache.tamaya.spi.PropertyValueBuilder;
 
 import java.util.Collections;
 import java.util.Date;
@@ -55,13 +56,13 @@ public class TestPropertySource implements PropertySource {
     @Override
     public PropertyValue get(String key) {
         return PropertyValue.builder(key, key + "Value", getName())
-                .addContextData("ordinal", String.valueOf(getOrdinal()))
-                .addContextData("createdAt", String.valueOf(new Date()))
+                .addMetaEntry("ordinal", String.valueOf(getOrdinal()))
+                .addMetaEntry("createdAt", String.valueOf(new Date()))
                 .build();
     }
 
     @Override
-    public Map<String, String> getProperties() {
+    public Map<String, PropertyValue> getProperties() {
         return Collections.emptyMap();
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/test/java/org/apache/tamaya/core/internal/DefaultConfigurationContextBuilderTest.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/internal/DefaultConfigurationContextBuilderTest.java b/code/core/src/test/java/org/apache/tamaya/core/internal/DefaultConfigurationContextBuilderTest.java
index 9564bda..05dd922 100644
--- a/code/core/src/test/java/org/apache/tamaya/core/internal/DefaultConfigurationContextBuilderTest.java
+++ b/code/core/src/test/java/org/apache/tamaya/core/internal/DefaultConfigurationContextBuilderTest.java
@@ -77,13 +77,13 @@ public class DefaultConfigurationContextBuilderTest {
     public void addPropertyFilters_Array() throws Exception {
         PropertyFilter filter1 = new PropertyFilter(){
             @Override
-            public String filterProperty(String value, FilterContext context) {
+            public PropertyValue filterProperty(PropertyValue value, FilterContext context) {
                 return value;
             }
         };
         PropertyFilter filter2 = new PropertyFilter(){
             @Override
-            public String filterProperty(String value, FilterContext context) {
+            public PropertyValue filterProperty(PropertyValue value, FilterContext context) {
                 return value;
             }
         };
@@ -103,13 +103,13 @@ public class DefaultConfigurationContextBuilderTest {
     public void removePropertyFilters_Array() throws Exception {
         PropertyFilter filter1 = new PropertyFilter(){
             @Override
-            public String filterProperty(String value, FilterContext context) {
+            public PropertyValue filterProperty(PropertyValue value, FilterContext context) {
                 return value;
             }
         };
         PropertyFilter filter2 = new PropertyFilter(){
             @Override
-            public String filterProperty(String value, FilterContext context) {
+            public PropertyValue filterProperty(PropertyValue value, FilterContext context) {
                 return value;
             }
         };
@@ -175,9 +175,10 @@ public class DefaultConfigurationContextBuilderTest {
         PropertyValueCombinationPolicy combPol = new PropertyValueCombinationPolicy(){
 
             @Override
-            public Map<String, String> collect(Map<String, String> currentValue, String key, PropertySource propertySource) {
+            public PropertyValue collect(PropertyValue currentValue, String key, PropertySource propertySource) {
                 return currentValue;
             }
+
         };
         ConfigurationContextBuilder b = new DefaultConfigurationContextBuilder()
                 .setPropertyValueCombinationPolicy(combPol);
@@ -192,7 +193,6 @@ public class DefaultConfigurationContextBuilderTest {
     }
 
 
-    @Priority(200)
     private static class TestPropertySource implements PropertySource{
 
         private String id;
@@ -206,6 +206,11 @@ public class DefaultConfigurationContextBuilderTest {
         }
 
         @Override
+        public int getOrdinal() {
+            return 200;
+        }
+
+        @Override
         public String getName() {
             return id!=null?id:"TestPropertySource";
         }
@@ -216,7 +221,7 @@ public class DefaultConfigurationContextBuilderTest {
         }
 
         @Override
-        public Map<String, String> getProperties() {
+        public Map<String, PropertyValue> getProperties() {
             return Collections.emptyMap();
         }
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/test/java/org/apache/tamaya/core/internal/DefaultConfigurationContextTest.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/internal/DefaultConfigurationContextTest.java b/code/core/src/test/java/org/apache/tamaya/core/internal/DefaultConfigurationContextTest.java
index 6ab5976..9d98a5e 100644
--- a/code/core/src/test/java/org/apache/tamaya/core/internal/DefaultConfigurationContextTest.java
+++ b/code/core/src/test/java/org/apache/tamaya/core/internal/DefaultConfigurationContextTest.java
@@ -145,7 +145,7 @@ public class DefaultConfigurationContextTest {
         PropertyFilter testFilter = new PropertyFilter() {
 
             @Override
-            public String filterProperty(String value, FilterContext context) {
+            public PropertyValue filterProperty(PropertyValue value, FilterContext context) {
                 return value;
             }
         };



[6/6] incubator-tamaya git commit: TAMAYA-253: Added replacement policy for raw evaluation.

Posted by an...@apache.org.
TAMAYA-253: Added replacement policy for raw evaluation.


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

Branch: refs/heads/master
Commit: 855342a86cf9efae48c375db9de9bb683c0a8336
Parents: 8c0081b
Author: anatole <an...@apache.org>
Authored: Sun Mar 5 21:24:25 2017 +0100
Committer: anatole <an...@apache.org>
Committed: Mon Mar 6 00:29:34 2017 +0100

----------------------------------------------------------------------
 .../core/internal/ConfigValueEvaluator.java     | 49 ++++++++++++++
 .../internal/DefaultConfigValueEvaluator.java   | 70 ++++++++++++++++++++
 ...he.tamaya.core.internal.ConfigValueEvaluator | 19 ++++++
 3 files changed, 138 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/855342a8/code/core/src/main/java/org/apache/tamaya/core/internal/ConfigValueEvaluator.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/ConfigValueEvaluator.java b/code/core/src/main/java/org/apache/tamaya/core/internal/ConfigValueEvaluator.java
new file mode 100644
index 0000000..0a3b211
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/ConfigValueEvaluator.java
@@ -0,0 +1,49 @@
+/*
+ * 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;
+
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * Component SPI which encapsulates the evaluation of a single or full <b>raw</b>value
+ * for a {@link ConfigurationContext}.
+ */
+public interface ConfigValueEvaluator {
+
+    /**
+     * Evaluates single value using a {@link ConfigurationContext}.
+     * @param key the config key, not null.
+     * @param context the context, not null.
+     * @return the value, or null.
+     */
+    PropertyValue evaluteRawValue(String key, ConfigurationContext context);
+
+    /**
+     * Evaluates all property values from a {@link ConfigurationContext}.
+     * @param context the context, not null.
+     * @return the value, or null.
+     */
+    Map<String, PropertyValue> evaluateRawValues(ConfigurationContext context);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/855342a8/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigValueEvaluator.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigValueEvaluator.java b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigValueEvaluator.java
new file mode 100644
index 0000000..f3b30a3
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigValueEvaluator.java
@@ -0,0 +1,70 @@
+/*
+ * 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;
+
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.PropertyFilter;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * Implementation of the Configuration API. This class uses the current {@link ConfigurationContext} to evaluate the
+ * chain of {@link PropertySource} and {@link PropertyFilter}
+ * instance to evaluate the current Configuration.
+ */
+public class DefaultConfigValueEvaluator implements ConfigValueEvaluator{
+
+    @Override
+    public PropertyValue evaluteRawValue(String key, ConfigurationContext context) {
+        PropertyValue unfilteredValue = null;
+        for (PropertySource propertySource : context.getPropertySources()) {
+            unfilteredValue = context.getPropertyValueCombinationPolicy().
+                    collect(unfilteredValue, key, propertySource);
+        }
+        if(unfilteredValue==null || unfilteredValue.getValue()==null){
+            return unfilteredValue;
+        }
+        return unfilteredValue;
+    }
+
+    @Override
+    public Map<String, PropertyValue> evaluateRawValues(ConfigurationContext context) {
+        Map<String, PropertyValue> result = new HashMap<>();
+        for (PropertySource propertySource : context.getPropertySources()) {
+            for (Map.Entry<String,PropertyValue> propEntry: propertySource.getProperties().entrySet()) {
+                PropertyValue unfilteredValue = result.get(propEntry.getKey());
+                unfilteredValue = context.getPropertyValueCombinationPolicy().
+                        collect(unfilteredValue, propEntry.getKey(), propertySource);
+                if(unfilteredValue!=null){
+                    result.put(unfilteredValue.getKey(), unfilteredValue);
+                }
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "DefaultConfigEvaluator{}";
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/855342a8/code/core/src/main/resources/META-INF/services/org.apache.tamaya.core.internal.ConfigValueEvaluator
----------------------------------------------------------------------
diff --git a/code/core/src/main/resources/META-INF/services/org.apache.tamaya.core.internal.ConfigValueEvaluator b/code/core/src/main/resources/META-INF/services/org.apache.tamaya.core.internal.ConfigValueEvaluator
new file mode 100644
index 0000000..624f0c1
--- /dev/null
+++ b/code/core/src/main/resources/META-INF/services/org.apache.tamaya.core.internal.ConfigValueEvaluator
@@ -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.DefaultConfigValueEvaluator
\ No newline at end of file