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 2016/02/02 17:16:13 UTC

[4/8] incubator-tamaya git commit: TAMAYA-136: Adding PropertyValue for PropertySource SPI.

TAMAYA-136: Adding PropertyValue for PropertySource SPI.


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

Branch: refs/heads/master
Commit: 80432aeb74f64e1d0f8a9cb22c7ebd88f8e7681c
Parents: eba49d8
Author: anatole <an...@apache.org>
Authored: Tue Feb 2 15:16:02 2016 +0100
Committer: anatole <an...@apache.org>
Committed: Tue Feb 2 15:16:02 2016 +0100

----------------------------------------------------------------------
 .../org/apache/tamaya/spi/FilterContext.java    | 107 +++----------------
 .../org/apache/tamaya/spi/PropertySource.java   |   6 +-
 .../org/apache/tamaya/spi/PropertyValue.java    |  63 +++++++++--
 .../apache/tamaya/spi/PropertyValueBuilder.java |  15 +--
 .../spi/PropertyValueCombinationPolicy.java     |  15 +--
 .../tamaya/spi/PropertyValueBuilderTest.java    |  33 ++++--
 .../apache/tamaya/spi/PropertyValueTest.java    |   9 +-
 7 files changed, 113 insertions(+), 135 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/80432aeb/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 105d7f4..7e81bd9 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
@@ -24,25 +24,25 @@ import java.util.Map;
 import java.util.Objects;
 
 /**
- * A conversion context containing all the required values for implementing conversion. Use the included #Builder
- * for creating new instances of. This class is thread-safe to use. Adding supported formats is synchronized.
+ * A filter context containing all the required values for implementing filtering.
  *
- * @see PropertyConverter
+ * @see PropertyFilter
  */
 public class FilterContext {
 
     private final String key;
     @Experimental
-    private Map<String, String> metaEntries = new HashMap();
+    private Map<String, String> configEntries = new HashMap();
 
     /**
-     * Private constructor used from builder.
-     *
-     * @param builder the builder, not null.
+     * Creates a new FilterContext.
+     * @param key the key under evaluation, not null.
+     * @param configEntries the raw configuration data available in the current evaluation context, not null.
      */
-    protected FilterContext(Builder builder) {
-        this.key = builder.key;
-        this.metaEntries.putAll(builder.metaEntries);
+    public FilterContext(String key, Map<String,String> configEntries) {
+        this.key = Objects.requireNonNull(key);
+        this.configEntries.putAll(configEntries);
+        this.configEntries = Collections.unmodifiableMap(this.configEntries);
     }
 
     /**
@@ -77,97 +77,16 @@ public class FilterContext {
      * @return the configuration instance, or null.
      */
     @Experimental
-    public Map<String, String> getMetaEntries() {
-        return metaEntries;
-    }
-
-    /**
-     * Property to check, if the entry filtered is actually accessed as single value, or as part of a full Map
-     * access. For both scenarios filtering may be different.
-     * @return true, if it is a directly accessed key.
-     */
-    @Experimental
-    public boolean isSingleAccessedProperty(){
-        return this.metaEntries.size()==1;
+    public Map<String, String> getConfigEntries() {
+        return configEntries;
     }
 
     @Override
     public String toString() {
         return "FilterContext{" +
                 "key='" + key + '\'' +
-                ", metaEntries=" + metaEntries +
+                ", configEntries=" + configEntries +
                 '}';
     }
 
-    /**
-     * Builder to create new instances of {@link FilterContext}.
-     */
-    public static final class Builder {
-        /**
-         * The accessed key, or null.
-         */
-        private String key;
-        private Map<String, String> metaEntries = new HashMap();
-
-        /**
-         * Creates a new Builder instance.
-         *
-         * @param key the requested key, may be null.
-         */
-        public Builder(String key, String value) {
-            this(key, Collections.<String, String>emptyMap());
-            metaEntries.put(key, value);
-        }
-
-        /**
-         * Creates a new Builder instance.
-         *
-         * @param metaData the configuration, not null.
-         * @param key      the requested key, may be null.
-         */
-        public Builder(String key, Map<String, String> metaData) {
-            this.key = key;
-            this.metaEntries.putAll(metaData);
-        }
-
-        /**
-         * Sets the key.
-         *
-         * @param key the key, not null.
-         * @return the builder instance, for chaining
-         */
-        public Builder setKey(String key) {
-            this.key = Objects.requireNonNull(key);
-            return this;
-        }
-
-        /**
-         * Sets the configuration.
-         *
-         * @param metaProperties the meta configuration, not null
-         * @return the builder instance, for chaining
-         */
-        public Builder setMetaProperties(Map<String, String> metaProperties) {
-            this.metaEntries.putAll(Objects.requireNonNull(metaProperties));
-            return this;
-        }
-
-        /**
-         * Builds a new context instance.
-         *
-         * @return a new context, never null.
-         */
-        public FilterContext build() {
-            return new FilterContext(this);
-        }
-
-
-        @Override
-        public String toString() {
-            return "Builder{" +
-                    "key='" + key + '\'' +
-                    ", metaEntries=" + metaEntries +
-                    '}';
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/80432aeb/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 14765eb..804adf5 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
@@ -92,10 +92,10 @@ public interface PropertySource {
      * Access a property.
      *
      * @param key the property's key, not null.
-     * @return the property value, including also its metadata. In case a value is null it is valid to return
-     * {#code null} here.
+     * @return the property value map, where {@code map.get(key) == value}, including also any metadata. In case a
+     * value is null, simply return {@code null}.
      */
-    PropertyValue get(String key);
+    Map<String,String> get(String key);
 
     /**
      * Access the current properties as Map. The resulting Map may not return all items accessible, e.g.

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/80432aeb/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 5529005..8d3559c 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,26 +18,41 @@
  */
 package org.apache.tamaya.spi;
 
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Objects;
 
 /**
- * Class modelling the result of a request for a property value.
+ * Class modelling the result of a request for a property value. A property value is basically identified by its key.
+ * There might be reasons, where one want to further analyze, which PropertySources provided a value and which not, so
+ * 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 {
     /** The requested key. */
     private String key;
-    /** The value found. */
-    private String value;
     /** Additional metadata provided by thhe provider. */
-    private Map<String,String> contextData;
+    private Map<String,String> configEntries = new HashMap<>();
 
     PropertyValue(PropertyValueBuilder builder){
         this.key = builder.key;
-        this.value = builder.value;
         if(builder.contextData!=null) {
-            this.contextData = new HashMap<>(builder.contextData);
+            this.configEntries.putAll(builder.contextData);
         }
+        this.configEntries.put(key, Objects.requireNonNull(builder.value));
+    }
+
+    /**
+     * Creates a new instance
+     * @param key the key, not null.
+     * @param value the value, not null.
+     * @param source the source, typically the name of the {@link PropertySource} providing the value, not null.
+     */
+    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."));
     }
 
     /**
@@ -54,20 +69,46 @@ public final class PropertyValue {
      * {@link PropertySource#get(String)}.
      */
     public String getValue() {
-        return value;
+        return configEntries.get(key);
     }
 
-    public Map<String, String> getContextData() {
-        return contextData;
+    /**
+     * Creates a full configuration map for this key, value pair and all its meta context data. This map
+     * is also used for subsequent processing, like value filtering.
+     * @return the property value entry map.
+     */
+    public Map<String, String> getConfigEntries() {
+        return Collections.unmodifiableMap(configEntries);
     }
 
     /**
      * 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 value){
-        return new PropertyValueBuilder(key, value);
+    public static PropertyValueBuilder builder(String key, String value, String source){
+        return new PropertyValueBuilder(key, value, source);
+    }
+
+    /**
+     * Creates a new PropertyValue without any metadata..
+     * @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 PropertyValue of(String key, String value, String source){
+        return new PropertyValue(key, value, source);
+    }
+
+    /**
+     * Access the given key from this value. Valid keys are the key or any meta-context key.
+     * @param key the key, not null.
+     * @return the value found, or null.
+     */
+    public String get(String key) {
+        return this.configEntries.get(key);
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/80432aeb/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 d75130b..349ee6c 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,16 +31,17 @@ public class PropertyValueBuilder {
     /** The property value. */
     String value;
     /** additional metadata entries (optional). */
-    Map<String,String> contextData;
+    Map<String,String> contextData = new HashMap<>();
 
     /**
      * Create a new builder instance, for a given
      * @param value the value, not null. If a value is null {@link PropertySource#get(String)} should return
      * {@code null}.
      */
-    public PropertyValueBuilder(String key, String value) {
+    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));
     }
 
     /**
@@ -63,11 +64,7 @@ public class PropertyValueBuilder {
      * @return the builder for chaining.
      */
     public PropertyValueBuilder setContextData(Map<String, String> contextData) {
-        if(this.contextData==null){
-            this.contextData = new HashMap<>();
-        } else{
-            this.contextData.clear();
-        }
+        this.contextData.clear();
         for(Map.Entry<String,String> en:contextData.entrySet()) {
             this.contextData.put("_"+this.key+'.'+en.getKey(), en.getValue());
         }
@@ -81,9 +78,6 @@ public class PropertyValueBuilder {
      * @return the builder for chaining.
      */
     public PropertyValueBuilder addContextData(String key, Object value) {
-        if(this.contextData==null){
-            this.contextData = new HashMap<>();
-        }
         this.contextData.put("_"+this.key+'.'+key, String.valueOf(Objects.requireNonNull(value)));
         return this;
     }
@@ -99,6 +93,7 @@ public class PropertyValueBuilder {
     @Override
     public String toString() {
         return "PropertyValueBuilder{" +
+                "key='" + key + '\'' +
                 "value='" + value + '\'' +
                 ", contextData=" + contextData +
                 '}';

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/80432aeb/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 11726f5..ad842d2 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,6 +18,8 @@
  */
 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
  * interface can be registered to get control how multiple PropertySources are combined. This is useful in cases
@@ -34,9 +36,9 @@ public interface PropertyValueCombinationPolicy {
     PropertyValueCombinationPolicy DEFAULT_OVERRIDING_COLLECTOR = new PropertyValueCombinationPolicy(){
 
         @Override
-        public String collect(String currentValue, String key, PropertySource propertySource) {
-            PropertyValue value = propertySource.get(key);
-            return value!=null?value.getValue():currentValue;
+        public Map<String,String> collect(Map<String,String> currentValue, String key, PropertySource propertySource) {
+            Map<String,String> value = propertySource.get(key);
+            return value!=null && value.get(key)!=null?value:currentValue;
         }
 
     };
@@ -47,7 +49,8 @@ public interface PropertyValueCombinationPolicy {
      * when the full configuration property map is accessed by calling
      * {@link org.apache.tamaya.Configuration#getProperties()}.
      *
-     * @param currentValue the current value, including null.
+     * @param currentValue the current value, including metadata entries. If no such key is present the current value
+     *                     is null.
      *                     The collector should either combine the existing value with value from {@code currentValue}
      *                     or replace the value in {@code currentValue} with {@code valueRead}, hereby returning the
      *                     result to be used as new {@code currentValue}.
@@ -56,8 +59,8 @@ public interface PropertyValueCombinationPolicy {
      *                       may be evaluated for additional meta-data, how the given values are to be combined.
      *                       Note that the value returned by a PropertySource can be null. In that case
      *                       {@code currentValue} should be returned in almost all cases.
-     * @return the value to be used for future evaluation.
+     * @return the value to be used for future evaluation, including metadata entries.
      */
-    String collect(String currentValue, String key, PropertySource propertySource);
+    Map<String,String> collect(Map<String,String> currentValue, String key, PropertySource propertySource);
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/80432aeb/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 7c8f349..5fdec2d 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
@@ -31,8 +31,28 @@ import static org.junit.Assert.*;
 public class PropertyValueBuilderTest {
 
     @Test
+    public void testKey() throws Exception {
+        PropertyValueBuilder b = new PropertyValueBuilder("k", "v", "testKey");
+        PropertyValue val = b.build();
+        assertEquals(val.getKey(),"k");
+    }
+
+    @Test
+    public void testValue() throws Exception {
+        PropertyValueBuilder b = new PropertyValueBuilder("k", "v", "testValue");
+        PropertyValue val = b.build();
+        assertEquals(val.getValue(),"v");
+        assertEquals(val.getConfigEntries().get("k"),"v");
+    }
+
+    @Test(expected=NullPointerException.class)
+    public void testKeyNullValue() throws Exception {
+        new PropertyValueBuilder("k", null, "testKeyNullValue");
+    }
+
+    @Test
     public void testSetContextData() throws Exception {
-        PropertyValueBuilder b = new PropertyValueBuilder("k", "v");
+        PropertyValueBuilder b = new PropertyValueBuilder("k", "v", "testSetContextData");
         Map<String,String> context = new HashMap<>();
         context.put("source", "testSetContextData");
         context.put("ts", String.valueOf(System.currentTimeMillis()));
@@ -41,8 +61,8 @@ public class PropertyValueBuilderTest {
         b.setContextData(context);
         context.remove("y");
         b.setContextData(context);
-        Map<String,String> contextData = b.build().getContextData();
-        assertEquals(contextData.size(), context.size());
+        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"));
@@ -50,13 +70,12 @@ public class PropertyValueBuilderTest {
 
     @Test
     public void testAddContextData() throws Exception {
-        PropertyValueBuilder b = new PropertyValueBuilder("k", "v");
-        b.addContextData("source", "testAddContextData");
+        PropertyValueBuilder b = new PropertyValueBuilder("k", "v", "testAddContextData");
         b.addContextData("ts", System.currentTimeMillis());
         b.addContextData("y", "yValue");
         b.addContextData("y", "y2");
-        Map<String,String> contextData = b.build().getContextData();
-        assertEquals(contextData.size(), 3);
+        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");

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/80432aeb/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 48fd23f..c6909ab 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
@@ -29,23 +29,24 @@ public class PropertyValueTest {
 
     @Test
     public void testGetKey() throws Exception {
-        PropertyValue pv = PropertyValue.builder("k", "v").build();
+        PropertyValue pv = PropertyValue.builder("k", "v", "testGetKey").build();
         assertEquals("k", pv.getKey());
     }
 
     @Test
     public void testGetValue() throws Exception {
-        PropertyValue pv = PropertyValue.builder("k", "v").build();
+        PropertyValue pv = PropertyValue.builder("k", "v", "testGetKey").build();
         assertEquals("v", pv.getValue());
     }
 
     @Test
     public void testGetContextData() throws Exception {
-        PropertyValue pv = PropertyValue.builder("k", "v")
+        PropertyValue pv = PropertyValue.builder("k", "v", "testGetKey")
                 .addContextData("k", "v2").build();
         assertEquals("v", pv.getValue());
         assertEquals("k", pv.getKey());
-        assertEquals("v2", pv.getContextData().get("_k.k"));
+        assertEquals("v2", pv.get("_k.k"));
+        assertEquals("testGetKey", pv.get("_k.source"));
     }
 
 }
\ No newline at end of file