Repository: incubator-tamaya
Updated Branches:
  refs/heads/configjsr 461221aab -> 7bf83f0bd


Updated to latest JST API changes (added ConfigValue).
Added support for automatic module.

Signed-off-by: Anatole Tresch <[email protected]>


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

Branch: refs/heads/configjsr
Commit: 7bf83f0bdd3e29a3666860751ed3adce605e2cde
Parents: 461221a
Author: Anatole Tresch <[email protected]>
Authored: Wed Mar 21 21:07:39 2018 +0100
Committer: Anatole Tresch <[email protected]>
Committed: Wed Mar 21 21:07:39 2018 +0100

----------------------------------------------------------------------
 code/base/bnd.bnd                               |   1 +
 .../org/apache/tamaya/base/ConfigContext.java   |  36 ++-
 .../org/apache/tamaya/base/ConfigValue.java     | 131 ++++----
 .../apache/tamaya/base/ConfigValueBuilder.java  |  73 +----
 .../base/DefaultCollectionConfigValue.java      |  75 +++++
 .../org/apache/tamaya/base/DefaultConfig.java   |  12 +
 .../apache/tamaya/base/DefaultConfigValue.java  | 305 +++++++++++++++++++
 .../org/apache/tamaya/base/ReflectionUtil.java  |  42 ---
 .../java/org/apache/tamaya/base/TypeUtils.java  |  10 +
 .../tamaya/base/convert/CompoundConverter.java  |  68 +++++
 .../tamaya/base/DefaultConfigValueTest.java     | 208 +++++++++++++
 .../base/convert/BigDecimalConverter.java       |  32 ++
 .../tamaya/base/convert/DoubleConverter.java    |  31 ++
 .../tamaya/base/convert/IntConverter.java       |  31 ++
 .../services/javax.config.spi.Converter         |   5 +-
 code/core/bnd.bnd                               |   1 +
 .../core/converters/BigIntegerConverter.java    |   2 +-
 .../tamaya/core/converters/ByteConverter.java   |   2 +-
 .../tamaya/core/converters/CharConverter.java   |   2 +-
 .../tamaya/core/converters/DoubleConverter.java |   2 +-
 .../tamaya/core/converters/FileConverter.java   |   2 +-
 .../tamaya/core/converters/LongConverter.java   |   2 +-
 .../tamaya/core/converters/NumberConverter.java |   2 +-
 .../converters/BigDecimalConverterTest.java     |  11 +-
 code/old/api/bnd.bnd                            |   1 +
 .../converters/BigDecimalConverter.java         |   2 +-
 .../internal/converters/BooleanConverter.java   |   2 +-
 .../internal/converters/ClassConverter.java     |   2 +-
 .../internal/converters/CurrencyConverter.java  |   2 +-
 .../internal/converters/DurationConverter.java  |   3 +-
 .../internal/converters/IntegerConverter.java   |   2 +-
 .../internal/converters/ShortConverter.java     |   2 +-
 .../core/internal/converters/URIConverter.java  |   2 +-
 33 files changed, 900 insertions(+), 204 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/base/bnd.bnd
----------------------------------------------------------------------
diff --git a/code/base/bnd.bnd b/code/base/bnd.bnd
index 41ce9eb..9ae02a8 100644
--- a/code/base/bnd.bnd
+++ b/code/base/bnd.bnd
@@ -9,6 +9,7 @@
 javac.source: 1.8
 javac.target: 1.8
 
+Automatic-Module-Name: org.apache.tamaya.spisupport
 Bundle-Version: ${version}.${tstamp}
 Bundle-Name: Apache Tamaya - SPI Support
 Bundle-SymbolicName: org.apache.tamaya.spisupport

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/base/src/main/java/org/apache/tamaya/base/ConfigContext.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/ConfigContext.java 
b/code/base/src/main/java/org/apache/tamaya/base/ConfigContext.java
index 99322f6..cfd8007 100644
--- a/code/base/src/main/java/org/apache/tamaya/base/ConfigContext.java
+++ b/code/base/src/main/java/org/apache/tamaya/base/ConfigContext.java
@@ -51,8 +51,12 @@ public interface ConfigContext {
         }
         return new ConfigContext() {
             @Override
-            public Iterable<ConfigSource> getConfigSources() {
-                return Objects.requireNonNull(config.getConfigSources());
+            public List<ConfigSource> getConfigSources() {
+                List<ConfigSource> configSources = new ArrayList<>();
+                for(ConfigSource cs:config.getConfigSources()){
+                    configSources.add(cs);
+                }
+                return configSources;
             }
 
             @Override
@@ -84,21 +88,21 @@ public interface ConfigContext {
      *
      * @return a sorted list of registered PropertySources.  The returned list 
need not be modifiable
      */
-    Iterable<ConfigSource> getConfigSources();
+    List<ConfigSource> getConfigSources();
 
-//    /**
-//     * Access a {@link ConfigSource} using its (unique) name.
-//     * @param name the propoerty source's name, not {@code null}.
-//     * @return the propoerty source found, or {@code null}.
-//     */
-//    default ConfigSource getSource(String name) {
-//        for(ConfigSource ps: getConfigSources()){
-//            if(name.equals(ps.getName())){
-//                return ps;
-//            }
-//        }
-//        return null;
-//    }
+    /**
+     * Access a {@link ConfigSource} using its (unique) name.
+     * @param name the propoerty source's name, not {@code null}.
+     * @return the propoerty source found, or {@code null}.
+     */
+    default ConfigSource getSource(String name) {
+        for(ConfigSource ps: getConfigSources()){
+            if(name.equals(ps.getName())){
+                return ps;
+            }
+        }
+        return null;
+    }
 
     /**
      * Access the current PropertyFilter instances.

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/base/src/main/java/org/apache/tamaya/base/ConfigValue.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/ConfigValue.java 
b/code/base/src/main/java/org/apache/tamaya/base/ConfigValue.java
index 697f79a..9e0a301 100644
--- a/code/base/src/main/java/org/apache/tamaya/base/ConfigValue.java
+++ b/code/base/src/main/java/org/apache/tamaya/base/ConfigValue.java
@@ -19,6 +19,7 @@
 package org.apache.tamaya.base;
 
 import java.io.Serializable;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
@@ -36,25 +37,26 @@ public final class ConfigValue implements Serializable{
     /** The value. */
     private String value;
     /** Additional metadata provided by the provider. */
-    private String metaEntry;
+    private Map<String, String> metaEntries = new HashMap<>();
 
     ConfigValue(ConfigValueBuilder builder){
         this.key = Objects.requireNonNull(builder.key);
         this.value = Objects.requireNonNull(builder.value);
-        this.metaEntry = builder.metaEntry;
+        this.metaEntries = builder.metaEntries;
     }
 
     /**
      * Creates a new instance
      * @param key the key, not {@code null}.
      * @param value the value, not {@code null}.
-     * @param metaEntry the source, typically the name of the {@link 
javax.config.spi.ConfigSource} providing
-     *               the value, not {@code null}.
+     * @param metaEntries the metaEntries, not {@code null}.
      */
-    private ConfigValue(String key, String value, String metaEntry){
+    private ConfigValue(String key, String value, Map<String,String> 
metaEntries){
         this.key = Objects.requireNonNull(key, "Key is required.");
         this.value = Objects.requireNonNull(value, "Value is required.");
-        this.metaEntry = metaEntry;
+        if(metaEntries!=null) {
+            this.metaEntries.putAll(metaEntries);
+        }
     }
 
     /**
@@ -79,8 +81,8 @@ public final class ConfigValue implements Serializable{
      * is also used for subsequent processing, like value filtering.
      * @return the property value entry map.
      */
-    public String getMetaEntry() {
-        return metaEntry;
+    public Map<String,String> getMetaEntries() {
+        return Collections.unmodifiableMap(metaEntries);
     }
 
     /**
@@ -110,16 +112,15 @@ public final class ConfigValue implements Serializable{
      * Creates a new PropertyValue without any metadata..
      * @param key the key, not {@code null}.
      * @param value the value.
-     * @param metaEntry the metaEntry, typically the name of the {@link 
javax.config.spi.ConfigSource}
-     *               providing the value, not  {@code null}.
+     * @param metaEntries the metaEntries, not  {@code null}.
      * @return a new property value instance, or {@code null},
      *         if the value passed is {@code null}..
      */
-    public static ConfigValue of(String key, String value, String metaEntry) {
+    public static ConfigValue of(String key, String value, Map<String,String> 
metaEntries) {
         if (value==null) {
             return null;
         }
-        return new ConfigValue(key, value, metaEntry);
+        return new ConfigValue(key, value, metaEntries);
     }
 
     /**
@@ -129,7 +130,7 @@ public final class ConfigValue implements Serializable{
     public ConfigValueBuilder toBuilder() {
         return new ConfigValueBuilder(this.getKey())
                 .setValue(this.getValue())
-        .setMetaEntry(this.metaEntry);
+        .addMetaEntries(this.metaEntries);
     }
 
     @Override
@@ -139,13 +140,13 @@ public final class ConfigValue implements Serializable{
         ConfigValue that = (ConfigValue) o;
         return Objects.equals(getKey(), that.getKey()) &&
                 Objects.equals(getValue(), that.getValue()) &&
-                Objects.equals(getMetaEntry(), that.getMetaEntry());
+                Objects.equals(getMetaEntries(), that.getMetaEntries());
     }
 
     @Override
     public int hashCode() {
         return Objects.hash(getKey(), getValue(),
-                getMetaEntry());
+                getMetaEntries());
     }
 
     @Override
@@ -153,57 +154,57 @@ public final class ConfigValue implements Serializable{
         return "PropertyValue{" +
                 "key='" + key + '\'' +
                 ", value='" + value + '\'' +
-                ", metaEntry='" + metaEntry + '\'' +
+                ", metaEntries='" + metaEntries + '\'' +
                 '}';
     }
 
-    /**
-     * Maps a map of {@code Map<String,String>} to a {@code 
Map<String,PropertyValue>}.
-     * @param config the String based map, not {@code null}.
-     * @return the corresponding value based map.
-     */
-    public static Map<String,ConfigValue> map(Map<String, String> config) {
-        Map<String,ConfigValue> result = new HashMap<>(config.size());
-        for(Map.Entry<String,String> en:config.entrySet()){
-            result.put(en.getKey(), ConfigValue.of(en.getKey(), en.getValue(), 
config.get(en.getKey()+"[meta]")));
-        }
-        return result;
-    }
-
-    /**
-     * Maps a map of {@code Map<String,String>} to a {@code 
Map<String,PropertyValue>}.
-     *
-     * @param config the String based map, not {@code null}.
-     * @param source the source name, not {@code null}.
-     * @param metaData additional metadata, not {@code null}.
-     * @return the corresponding value based map.
-     */
-    public static Map<String,ConfigValue> map(Map<String, String> config, 
String source,
-                                              Map<String,String> metaData) {
-        Objects.requireNonNull(config, "Config must be given.");
-        Objects.requireNonNull(source, "Source must be given.");
-        Objects.requireNonNull(metaData, "Meta data must be given.");
-
-        Map<String,ConfigValue> result = new HashMap<>(config.size());
-
-        for(Map.Entry<String,String> en:config.entrySet()){
-            ConfigValue value = new ConfigValueBuilder(en.getKey(), 
source).setValue(en.getValue())
-                                                                               
.addMetaEntries(metaData).build();
-            result.put(en.getKey(), value);
-        }
-        return result;
-    }
-
-    public Map<? extends String, ? extends String> asMap() {
-        Map<String,String> map = new HashMap<>();
-        map.put(key, value);
-        map.put(key+"[meta]", this.metaEntry);
-        return map;
-    }
-
-    public static ConfigValue of(String key, Map<String, String> 
rawProperties) {
-        String value = rawProperties.get(key);
-        String meta = rawProperties.get(key+"[meta]");
-        return new ConfigValue(key, value, meta);
-    }
+//    /**
+//     * Maps a map of {@code Map<String,String>} to a {@code 
Map<String,PropertyValue>}.
+//     * @param config the String based map, not {@code null}.
+//     * @return the corresponding value based map.
+//     */
+//    public static Map<String,ConfigValue> map(Map<String, String> config) {
+//        Map<String,ConfigValue> result = new HashMap<>(config.size());
+//        for(Map.Entry<String,String> en:config.entrySet()){
+//            result.put(en.getKey(), ConfigValue.of(en.getKey(), 
en.getValue(), config.get(en.getKey()+"[meta]")));
+//        }
+//        return result;
+//    }
+//
+//    /**
+//     * Maps a map of {@code Map<String,String>} to a {@code 
Map<String,PropertyValue>}.
+//     *
+//     * @param config the String based map, not {@code null}.
+//     * @param source the source name, not {@code null}.
+//     * @param metaData additional metadata, not {@code null}.
+//     * @return the corresponding value based map.
+//     */
+//    public static Map<String,ConfigValue> map(Map<String, String> config, 
String source,
+//                                              Map<String,String> metaData) {
+//        Objects.requireNonNull(config, "Config must be given.");
+//        Objects.requireNonNull(source, "Source must be given.");
+//        Objects.requireNonNull(metaData, "Meta data must be given.");
+//
+//        Map<String,ConfigValue> result = new HashMap<>(config.size());
+//
+//        for(Map.Entry<String,String> en:config.entrySet()){
+//            ConfigValue value = new ConfigValueBuilder(en.getKey(), 
source).setValue(en.getValue())
+//                                                                             
  .addMetaEntries(metaData).build();
+//            result.put(en.getKey(), value);
+//        }
+//        return result;
+//    }
+//
+//    public Map<? extends String, ? extends String> asMap() {
+//        Map<String,String> map = new HashMap<>();
+//        map.put(key, value);
+//        map.put(key+"[meta]", this.metaEntries);
+//        return map;
+//    }
+//
+//    public static ConfigValue of(String key, Map<String, String> 
rawProperties) {
+//        String value = rawProperties.get(key);
+//        String meta = rawProperties.get(key+"[meta]");
+//        return new ConfigValue(key, value, meta);
+//    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/base/src/main/java/org/apache/tamaya/base/ConfigValueBuilder.java
----------------------------------------------------------------------
diff --git 
a/code/base/src/main/java/org/apache/tamaya/base/ConfigValueBuilder.java 
b/code/base/src/main/java/org/apache/tamaya/base/ConfigValueBuilder.java
index 259a5be..986a321 100644
--- a/code/base/src/main/java/org/apache/tamaya/base/ConfigValueBuilder.java
+++ b/code/base/src/main/java/org/apache/tamaya/base/ConfigValueBuilder.java
@@ -31,11 +31,11 @@ public class ConfigValueBuilder {
     /** The property value. */
     String value;
     /** additional metadata entries (optional). */
-    String metaEntry;
+    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 
#metaEntry}
+     * Before calling build at least a {@link #value} and its {@link 
#metaEntries}
      * must be set.
      */
     ConfigValueBuilder(String key){
@@ -53,26 +53,12 @@ public class ConfigValueBuilder {
     }
 
     /**
-     * Create a new builder instance, for a given set of parameters.
-     *
-     * @param key to access a property value.
-     * @param value the value, not {@code null}. If a value is  {@code null}
-     *              {@link javax.config.spi.ConfigSource#getValue(String)} 
should return {@code null}.
-     * @param metaEntry property metaEntry.
-     */
-    ConfigValueBuilder(String key, String value, String metaEntry) {
-        this.key = Objects.requireNonNull(key);
-        this.value = value;
-        this.metaEntry = Objects.requireNonNull(metaEntry);
-    }
-
-    /**
      * Replaces/sets the context data.
-     * @param metaEntry the context data to be applied.
+     * @param metaEntries the context data to be applied.
      * @return the builder for chaining.
      */
-    public ConfigValueBuilder setMetaEntry(String metaEntry) {
-        this.metaEntry = metaEntry;
+    public ConfigValueBuilder addMetaEntries(Map<String,String> metaEntries) {
+        this.metaEntries.putAll(metaEntries);
         return this;
     }
 
@@ -85,48 +71,7 @@ public class ConfigValueBuilder {
     public ConfigValueBuilder addMetaEntry(String key, String value) {
         Objects.requireNonNull(key, "Meta key must be given.");
         Objects.requireNonNull(value, "Meta value must be given.");
-        if(metaEntry==null){
-            metaEntry = key+"="+value;
-        }else{
-            metaEntry = "\n" + key+"="+value;
-        }
-        return this;
-    }
-
-    /**
-     * Adds the context data given.
-     * @param metaEntries the context data to be applied, not {@code null}.
-     * @return the builder for chaining.
-     */
-    public ConfigValueBuilder addMetaEntries(Map<String, String> metaEntries) {
-        Properties props = new Properties();
-        props.putAll(metaEntries);
-        StringWriter stringWriter = new StringWriter();
-        try {
-            props.store(stringWriter, null);
-            stringWriter.flush();
-            if(metaEntry==null){
-                metaEntry = stringWriter.toString();
-            }else{
-                metaEntry += '\n' + stringWriter.toString();
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return this;
-    }
-
-    /**
-     * Adds the context data given as JSON object.
-     * @param meta the context data in JSON format, not {@code null}.
-     * @return the builder for chaining.
-     */
-    public ConfigValueBuilder addMetaEntry(String meta) {
-        if(metaEntry==null){
-            metaEntry = meta;
-        }else{
-            metaEntry += '\n' + meta;
-        }
+        metaEntries.put(key, value);
         return this;
     }
 
@@ -134,8 +79,8 @@ public class ConfigValueBuilder {
      * Get the value's context data.
      * @return the context data, not {@code null}.
      */
-    public String getMetaEntry() {
-        return metaEntry;
+    public Map<String,String> getMetaEntries() {
+        return Collections.unmodifiableMap(metaEntries);
     }
 
     /**
@@ -172,7 +117,7 @@ public class ConfigValueBuilder {
         return "PropertyValueBuilder{" +
                 "key='" + key + '\'' +
                 "value='" + value + '\'' +
-                ", metaEntry=" + metaEntry +
+                ", metaEntries=" + metaEntries +
                 '}';
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/base/src/main/java/org/apache/tamaya/base/DefaultCollectionConfigValue.java
----------------------------------------------------------------------
diff --git 
a/code/base/src/main/java/org/apache/tamaya/base/DefaultCollectionConfigValue.java
 
b/code/base/src/main/java/org/apache/tamaya/base/DefaultCollectionConfigValue.java
new file mode 100644
index 0000000..576bb9b
--- /dev/null
+++ 
b/code/base/src/main/java/org/apache/tamaya/base/DefaultCollectionConfigValue.java
@@ -0,0 +1,75 @@
+/*
+ * 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.base;
+
+import javax.config.spi.Converter;
+import java.util.*;
+import java.util.function.Supplier;
+
+/**
+ * Implementation of {@link ConfigValue}, which parses and returns a 
collection of items.
+ * @param <T> the collection type.
+ * @param <S> the item type.
+ */
+public class DefaultCollectionConfigValue<S, T extends Collection<S>> extends 
DefaultConfigValue<T> {
+
+    /** Supplier that creates the collection instances to use. */
+    private Supplier<T> collectionSupplier;
+
+    /**
+     * Create a new instance.
+     * @param configValue the original config value.
+     * @param targetClass the containing item class, used for converter lookup 
if no custom converter
+     *                    is set.
+     */
+    public DefaultCollectionConfigValue(DefaultConfigValue<T> configValue, 
Class targetClass, Supplier<T> collectionSupplier) {
+        super(configValue, targetClass);
+        this.collectionSupplier = Objects.requireNonNull(collectionSupplier);
+    }
+
+    @Override
+    public Optional<T> getOptionalValue() {
+        String value = textValue;
+        if(value==null){
+            if(defaultValue!=null){
+                value = defaultTextValue;
+            }
+        }
+        if(value==null) {
+            return Optional.ofNullable(defaultValue);
+        }
+        String[] parsedItems = parseItems(value);
+        T items = collectionSupplier.get();
+        Converter converter = getConverter(targetClass);
+        for(String itemValue:parsedItems){
+            items.add((S)converter.convert(itemValue));
+        }
+        return Optional.of(items);
+    }
+
+    /**
+     * Parses the input value as a comma separated list.
+     * @param value
+     * @return
+     */
+    private static String[] parseItems(String value) {
+        return value.split(",");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/base/src/main/java/org/apache/tamaya/base/DefaultConfig.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/DefaultConfig.java 
b/code/base/src/main/java/org/apache/tamaya/base/DefaultConfig.java
index b1e5849..e6850eb 100644
--- a/code/base/src/main/java/org/apache/tamaya/base/DefaultConfig.java
+++ b/code/base/src/main/java/org/apache/tamaya/base/DefaultConfig.java
@@ -25,10 +25,12 @@ import org.apache.tamaya.base.filter.Filter;
 import org.apache.tamaya.base.filter.FilterManager;
 
 import javax.config.Config;
+import javax.config.ConfigValue;
 import javax.config.spi.ConfigSource;
 import javax.config.spi.Converter;
 import java.lang.reflect.Type;
 import java.util.*;
+import java.util.function.Consumer;
 import java.util.logging.Logger;
 
 /**
@@ -103,6 +105,11 @@ public class DefaultConfig implements Config, 
ConfigContextSupplier {
         return Optional.ofNullable(val);
     }
 
+    @Override
+    public ConfigValue<String> access(String key) {
+        return new DefaultConfigValue(this, key, String.class);
+    }
+
     /**
      * Get the current properties, composed by the loaded {@link ConfigSource} 
and filtered
      * by registered {@link Filter}.
@@ -120,6 +127,11 @@ public class DefaultConfig implements Config, 
ConfigContextSupplier {
         return configSourceManager.getSources();
     }
 
+    @Override
+    public void registerConfigChangedListener(Consumer<Set<String>> consumer) {
+        throw new UnsupportedOperationException("Not yet implemented.");
+    }
+
 
     public <T> T getOrDefault(String key, Class<T> type, T defaultValue) {
         Objects.requireNonNull(key);

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/base/src/main/java/org/apache/tamaya/base/DefaultConfigValue.java
----------------------------------------------------------------------
diff --git 
a/code/base/src/main/java/org/apache/tamaya/base/DefaultConfigValue.java 
b/code/base/src/main/java/org/apache/tamaya/base/DefaultConfigValue.java
new file mode 100644
index 0000000..0e394be
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/DefaultConfigValue.java
@@ -0,0 +1,305 @@
+/*
+ * 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.base;
+
+import org.apache.tamaya.base.convert.CompoundConverter;
+
+import javax.config.ConfigValue;
+import javax.config.spi.Converter;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Implements the builder styled {@link ConfigValue}.
+ * @param <T> the item type
+ */
+public class DefaultConfigValue<T> implements ConfigValue<T> {
+
+    private static final Logger LOG = 
Logger.getLogger(DefaultConfigValue.class.getName());
+
+    private final DefaultConfig config;
+    private final String key;
+    private String resolvedKey;
+    protected String defaultTextValue;
+    protected String textValue;
+    protected T defaultValue;
+    private T lastValue;
+    private ConfigChanged configChangeListener;
+    protected Class targetClass;
+    private Converter<T> converter;
+    private boolean evaluateVariables;
+    private TimeUnit cacheDurationTimeUnit;
+    private long cacheDuration;
+    private String[] lookupChain;
+
+
+    /**
+     * Creates a new instance.
+     * @param config the underlying configuration, not null.
+     * @param key
+     * @param targetClass
+     */
+    public DefaultConfigValue(DefaultConfig config, String key, Class 
targetClass) {
+        this.config = Objects.requireNonNull(config);
+        this.key = Objects.requireNonNull(key);
+        this.targetClass = Objects.requireNonNull(targetClass);
+        if(lastValue!=null && 
!lastValue.getClass().isAssignableFrom(targetClass)){
+            lastValue = null;
+        }
+        if(defaultValue!=null && 
!defaultValue.getClass().isAssignableFrom(targetClass)){
+            defaultValue = null;
+        }
+        loadValue();
+    }
+
+    /**
+     * Constructor used internally and by {@link 
DefaultCollectionConfigValue}, when a custom converter has been
+     * applied.
+     * @param configValue the base instance, not null.
+     * @param converter the custom converter, not null.
+     */
+    DefaultConfigValue(DefaultConfigValue configValue, Converter<T> converter) 
{
+        this(configValue);
+        this.converter = Objects.requireNonNull(converter);
+        this.lastValue=null;
+        loadValue();
+    }
+
+    /**
+     * Constructor used internally and by {@link 
DefaultCollectionConfigValue}, when a new target type has been
+     * applied.
+     * @param configValue the base instance, not null.
+     * @param targetClass the target class, not null.
+     */
+    DefaultConfigValue(DefaultConfigValue configValue, Class targetClass) {
+        this(configValue);
+        this.targetClass = Objects.requireNonNull(targetClass);
+    }
+
+    /**
+     * Constructor to copy the instance variables from the other instance.
+     * @param configValue the other instance.
+     */
+    private DefaultConfigValue(DefaultConfigValue configValue) {
+        this.config = configValue.config;
+        this.key = configValue.key;
+        this.evaluateVariables = configValue.evaluateVariables;
+        this.converter = configValue.converter;
+        this.cacheDuration = configValue.cacheDuration;
+        this.cacheDurationTimeUnit = configValue.cacheDurationTimeUnit;
+        this.defaultTextValue = configValue.defaultTextValue;
+        this.textValue = configValue.textValue;
+        this.configChangeListener = configValue.configChangeListener;
+        this.converter = configValue.converter;
+        this.targetClass = configValue.targetClass;
+        if(configValue.lastValue!=null && 
!targetClass.getClass().isAssignableFrom(configValue.lastValue.getClass())){
+            lastValue = (T)configValue.lastValue;
+        }
+        if(configValue.defaultValue!=null && 
!targetClass.getClass().isAssignableFrom(configValue.defaultValue.getClass())){
+            defaultValue = (T)configValue.defaultValue;
+        }
+    }
+
+    @Override
+    public <N> ConfigValue<N> as(Class<N> type) {
+        return new DefaultConfigValue<>(this, type);
+    }
+
+    @Override
+    public ConfigValue<List<T>> asList() {
+        return new DefaultCollectionConfigValue(this, targetClass, 
ArrayList::new);
+    }
+
+    @Override
+    public ConfigValue<Set<T>> asSet() {
+        return new DefaultCollectionConfigValue(this, targetClass, 
HashSet::new);
+    }
+
+    /**
+     * Creates a new converter based on the converters available in the 
current config.
+     * @param targetClass the target class, not null
+     * @param <N> the target type, not unll
+     * @return a compund converter (may be empty), never null.
+     */
+    protected <N> Converter<N> getConverter(Class targetClass) {
+        if(String.class.equals(targetClass)){
+            return (s) -> (N)s;
+        }
+        return new 
CompoundConverter(config.getConfigContext().getConverters(targetClass));
+    }
+
+
+    @Override
+    public <N> ConfigValue<N> useConverter(Converter<N> converter) {
+        return new DefaultConfigValue<>(this, converter);
+    }
+
+    @Override
+    public ConfigValue<T> withDefault(T defaultValue) {
+        DefaultConfigValue<T> newVal = new DefaultConfigValue<>(this, 
targetClass);
+        newVal.defaultValue = Objects.requireNonNull(defaultValue);
+        return newVal;
+    }
+
+    @Override
+    public ConfigValue<T> withStringDefault(String defaultValue) {
+        DefaultConfigValue<T> newVal = new DefaultConfigValue<>(this, 
targetClass);
+        newVal.defaultTextValue = Objects.requireNonNull(defaultValue);
+        return newVal;
+    }
+
+    @Override
+    public ConfigValue<T> cacheFor(long duration, TimeUnit timeUnit) {
+        DefaultConfigValue<T> newVal = new DefaultConfigValue<>(this, 
targetClass);
+        newVal.cacheDurationTimeUnit = Objects.requireNonNull(timeUnit);
+        newVal.cacheDuration = duration;
+        return newVal;
+    }
+
+    @Override
+    public ConfigValue<T> evaluateVariables(boolean b) {
+        DefaultConfigValue<T> newVal = new DefaultConfigValue<>(this, 
targetClass);
+        newVal.evaluateVariables = Objects.requireNonNull(evaluateVariables);
+        return newVal;
+    }
+
+    @Override
+    public ConfigValue<T> withLookupChain(String... lookupChain) {
+        DefaultConfigValue<T> newVal = new DefaultConfigValue<>(this, 
targetClass);
+        newVal.lookupChain = Objects.requireNonNull(lookupChain.clone());
+        return newVal;
+    }
+
+    @Override
+    public ConfigValue<T> onChange(ConfigChanged configChangeListener) {
+        DefaultConfigValue<T> newVal = new DefaultConfigValue<>(this, 
targetClass);
+        newVal.configChangeListener = 
Objects.requireNonNull(configChangeListener);
+        return newVal;
+    }
+
+    @Override
+    public T getValue() {
+        return getOptionalValue().orElseThrow(NoSuchElementException::new);
+    }
+
+    @Override
+    public Optional<T> getOptionalValue() {
+        loadValue();
+        String value = textValue;
+        T result = null;
+        if(value==null){
+            if(defaultValue!=null){
+                result = defaultValue;
+            }
+            value = defaultTextValue;
+        }
+        if(result==null) {
+            if (value != null) {
+                if (converter != null) {
+                    result = converter.convert(value);
+                } else {
+                    result = (T) getConverter(targetClass).convert(value);
+                }
+            }
+        }
+        if (!Objects.equals(this.lastValue, result)) {
+            try{
+                if(configChangeListener!=null) {
+                    configChangeListener.onValueChange(key, this.lastValue, 
result);
+                }
+            }catch(Exception e){
+                LOG.log(Level.SEVERE, "Error calling config change listener: " 
+ configChangeListener, e);
+            }
+            this.lastValue = result;
+        }
+        return Optional.ofNullable(result);
+    }
+
+    @Override
+    public String getKey() {
+        return key;
+    }
+
+    @Override
+    public String getResolvedKey() {
+        return resolvedKey;
+    }
+
+    @Override
+    public T getDefaultValue() {
+        return defaultValue;
+    }
+
+    protected final void loadValue(){
+        List<String> keys = evaluateKeys();
+        Optional<String> currentValue = null;
+        String keyFound = null;
+        for(String key:keys){
+            currentValue = config.getOptionalValue(key, String.class);
+            if(currentValue.isPresent()){
+                keyFound = key;
+                break;
+            }
+        }
+        if(currentValue!=null){
+             this.textValue = currentValue.orElse(null);
+        }
+        this.resolvedKey = keyFound;
+    }
+
+
+    /*
+    some.server.url.myComp.Production</li>
+         *     <li>"some.server.url.myComp</li>
+         *     <li>"some.server.url.Production</li>
+         *     <li>"some.server.url
+     */
+    List<String> evaluateKeys() {
+        if(lookupChain==null){
+            return Collections.singletonList(key);
+        }
+        List<String> keys = new ArrayList<>(lookupChain.length * 
(lookupChain.length-1)/2);
+        for(int i=0;i<lookupChain.length;i++){
+            keys.add(key+'.'+lookupChain[i]);
+            for(int j=0;i<lookupChain.length;j++){
+                keys.add(key+'.'+lookupChain[i]+'.' + lookupChain[j]);
+            }
+        }
+        keys.add(key);
+        return keys;
+    }
+
+    @Override
+    public String toString() {
+        return "DefaultConfigValue{" +
+                "config=" + config +
+                ", key=" + key +
+                ", targetClass=" + targetClass +
+                ", textValue='" + textValue + '\'' +
+                ", defaultTextValue='" + defaultTextValue + '\'' +
+                ", lastValue='" + textValue + '\'' +
+                ", defaultValue=" + defaultValue +
+                ", configChangeListener=" + configChangeListener +
+                ", converter=" + converter +
+                '}';
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/base/src/main/java/org/apache/tamaya/base/ReflectionUtil.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/ReflectionUtil.java 
b/code/base/src/main/java/org/apache/tamaya/base/ReflectionUtil.java
deleted file mode 100644
index 85d2dc3..0000000
--- a/code/base/src/main/java/org/apache/tamaya/base/ReflectionUtil.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tamaya.base;
-
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-
-
-/**
- * Small utility class used by other parts.
- */
-public final class ReflectionUtil {
-
-    private ReflectionUtil(){}
-
-    public static ParameterizedType getParametrizedType(Class<?> clazz) {
-        Type[] genericTypes = clazz.getGenericInterfaces();
-        for (Type type : genericTypes) {
-            if (type instanceof ParameterizedType) {
-                return (ParameterizedType) type;
-            }
-
-        }
-        return null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/base/src/main/java/org/apache/tamaya/base/TypeUtils.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/TypeUtils.java 
b/code/base/src/main/java/org/apache/tamaya/base/TypeUtils.java
index 8dc3542..f23b479 100644
--- a/code/base/src/main/java/org/apache/tamaya/base/TypeUtils.java
+++ b/code/base/src/main/java/org/apache/tamaya/base/TypeUtils.java
@@ -36,6 +36,16 @@ public final class TypeUtils {
     private TypeUtils() {
     }
 
+    public static ParameterizedType getParametrizedType(Class<?> clazz) {
+        Type[] genericTypes = clazz.getGenericInterfaces();
+        for (Type type : genericTypes) {
+            if (type instanceof ParameterizedType) {
+                return (ParameterizedType) type;
+            }
+
+        }
+        return null;
+    }
 
     /**
      * Checks the current implemented generic interfaces and evaluates the 
given single type parameter.

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/base/src/main/java/org/apache/tamaya/base/convert/CompoundConverter.java
----------------------------------------------------------------------
diff --git 
a/code/base/src/main/java/org/apache/tamaya/base/convert/CompoundConverter.java 
b/code/base/src/main/java/org/apache/tamaya/base/convert/CompoundConverter.java
new file mode 100644
index 0000000..47af68b
--- /dev/null
+++ 
b/code/base/src/main/java/org/apache/tamaya/base/convert/CompoundConverter.java
@@ -0,0 +1,68 @@
+/*
+ * 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.base.convert;
+
+import javax.config.spi.Converter;
+import java.util.List;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Converter which implements a {@link Converter} based on multiple converter 
instances.
+ * @param <C>
+ */
+public final class CompoundConverter<C> implements Converter<C> {
+
+    private static final Logger LOG = 
Logger.getLogger(CompoundConverter.class.getName());
+
+    /** The delegating converter list, not null.*/
+    private List<Converter<C>> converters;
+
+    /**
+     * Creates a new converter.
+     * @param converters the converter to delegate to in order of precedence 
(most significant first), not null.
+     */
+    public CompoundConverter(List<Converter<C>> converters) {
+        this.converters = Objects.requireNonNull(converters);
+    }
+
+
+    @Override
+    public C convert(String value) {
+        for(Converter<C> converter:converters){
+            try{
+                C result = converter.convert(value);
+                if(result!=null){
+                    return result;
+                }
+            }catch(Exception e){
+                LOG.log(Level.WARNING, e, () -> "Converter failed for value: " 
+ value);
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public String toString() {
+        return "CompoundConverter{" +
+                "converters=" + converters +
+                '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/base/src/test/java/org/apache/tamaya/base/DefaultConfigValueTest.java
----------------------------------------------------------------------
diff --git 
a/code/base/src/test/java/org/apache/tamaya/base/DefaultConfigValueTest.java 
b/code/base/src/test/java/org/apache/tamaya/base/DefaultConfigValueTest.java
new file mode 100644
index 0000000..b71098f
--- /dev/null
+++ b/code/base/src/test/java/org/apache/tamaya/base/DefaultConfigValueTest.java
@@ -0,0 +1,208 @@
+/*
+ * 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.base;
+
+import org.junit.Test;
+
+import javax.config.ConfigProvider;
+import javax.config.ConfigValue;
+import javax.config.spi.Converter;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests for {@link DefaultConfigValue}.
+ */
+public class DefaultConfigValueTest {
+
+    private DefaultConfigValue<String> value = new DefaultConfigValue<>(
+            (DefaultConfig)ConfigProvider.getConfig(), "java.version", 
String.class);
+    private DefaultConfigValue<String> notExisting = new DefaultConfigValue<>(
+            (DefaultConfig)ConfigProvider.getConfig(), "notExisting", 
String.class);
+
+    @Test
+    public void as() throws Exception {
+        ConfigValue<Integer> val = notExisting
+                .withStringDefault("123")
+                .as(Integer.class);
+        assertNotNull(val);
+        assertEquals(Integer.valueOf("123"), val.getValue());
+        ConfigValue<BigDecimal> val2 = val.as(BigDecimal.class);
+        assertNotNull(val2);
+        assertEquals(new BigDecimal("123"), val2.getValue());
+    }
+
+    @Test
+    public void asList() throws Exception {
+        ConfigValue<List<String>> val = value.asList();
+        assertNotNull(val);
+        assertNotNull(val.getValue());
+        assertFalse(val.getValue().isEmpty());
+        assertEquals(val.getValue().size(), 1);
+        assertEquals(val.getValue().get(0), 
System.getProperty("java.version"));
+    }
+
+    @Test
+    public void asSet() throws Exception {
+        ConfigValue<Set<String>> val = value.asSet();
+        assertNotNull(val);
+        assertNotNull(val.getValue());
+        assertFalse(val.getValue().isEmpty());
+        assertEquals(val.getValue().size(), 1);
+        assertEquals(val.getValue().iterator().next(), 
System.getProperty("java.version"));
+    }
+
+    @Test
+    public void getConverter() throws Exception {
+        Integer val = notExisting
+                .withStringDefault("123")
+                .as(Integer.class)
+                .getValue();
+        assertNotNull(val);
+    }
+
+    @Test
+    public void useConverter() throws Exception {
+        ConfigValue<Integer> val = value.useConverter(new Converter<Integer>() 
{
+            @Override
+            public Integer convert(String s) {
+               return new Integer(1234);
+            }
+        });
+        assertNotNull(val);
+        assertEquals(new Integer(1234), val.getValue());
+    }
+
+    @Test
+    public void withDefault() throws Exception {
+        ConfigValue<Double> val = notExisting.as(Double.class)
+        .withDefault(Double.valueOf("123.45"));
+        assertNotNull(val);
+        assertEquals(Double.valueOf("123.45"), val.getDefaultValue());
+        assertEquals(Double.valueOf("123.45"), val.getValue());
+    }
+
+    @Test
+    public void withStringDefault() throws Exception {
+        ConfigValue<String> val = notExisting.withStringDefault("12345");
+        assertNotNull(val);
+        assertEquals("12345", val.getValue());
+        assertEquals(null, val.getDefaultValue());
+    }
+
+    @Test
+    public void cacheFor() throws Exception {
+        ConfigValue<String> val = value.cacheFor(1, TimeUnit.SECONDS);
+        assertNotNull(val);
+    }
+
+    @Test
+    public void evaluateVariables() throws Exception {
+        ConfigValue<String> val = value.evaluateVariables(true);
+        assertNotNull(val);
+
+        val = value.evaluateVariables(false);
+        assertNotNull(val);
+    }
+
+    @Test
+    public void withLookupChain() throws Exception {
+        ConfigValue<String> val = value.withLookupChain("");
+        assertNotNull(val);
+        val = value.withLookupChain("a");
+        assertNotNull(val);
+        val = value.withLookupChain("a", "b");
+        assertNotNull(val);
+    }
+
+    @Test
+    public void onChange() throws Exception {
+        String[] keyChanged = new String[1];
+        String[] oldVal = new String[1];
+        String[] newVal = new String[1];
+        ConfigValue<String> val = notExisting.onChange(new 
ConfigValue.ConfigChanged() {
+            @Override
+            public <T> void onValueChange(String k, T o, T n) {
+                keyChanged[0] = k;
+                oldVal[0] = (String)o;
+                newVal[0] = (String)n;
+            }
+        });
+        assertNotNull(val);
+        val = val.withDefault("123");
+        val.getOptionalValue();
+        assertEquals(keyChanged[0], notExisting.getKey());
+        assertEquals(oldVal[0], null);
+        assertEquals(newVal[0], "123");
+        val = val.withDefault("1234");
+        val.getOptionalValue();
+        assertEquals(keyChanged[0], notExisting.getKey());
+        assertEquals(oldVal[0], "123");
+        assertEquals(newVal[0], "1234");
+    }
+
+    @Test
+    public void getValue() throws Exception {
+        assertEquals(System.getProperty("java.version"), value.getValue());
+    }
+
+    @Test
+    public void getOptionalValue() throws Exception {
+        Optional<String> optValue = value.getOptionalValue();
+        assertNotNull(optValue);
+        assertTrue(optValue.isPresent());
+        assertEquals(System.getProperty("java.version"), optValue.get());
+        assertFalse(notExisting.getOptionalValue().isPresent());
+    }
+
+    @Test
+    public void getKey() throws Exception {
+        assertEquals("java.version", value.getKey());
+    }
+
+    @Test
+    public void getResolvedKey() throws Exception {
+        assertEquals("java.version", value.getResolvedKey());
+    }
+
+    @Test
+    public void getDefaultValue() throws Exception {
+        assertNull(value.getDefaultValue());
+    }
+
+    @Test
+    public void evaluateKeys() throws Exception {
+        List<String> keys = value.evaluateKeys();
+        assertNotNull(keys);
+        assertEquals(keys.size(), 1);
+        assertTrue(keys.contains("java.version"));
+    }
+
+    @Test
+    public void testToString() throws Exception {
+        assertNotNull(value.toString());
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/base/src/test/java/org/apache/tamaya/base/convert/BigDecimalConverter.java
----------------------------------------------------------------------
diff --git 
a/code/base/src/test/java/org/apache/tamaya/base/convert/BigDecimalConverter.java
 
b/code/base/src/test/java/org/apache/tamaya/base/convert/BigDecimalConverter.java
new file mode 100644
index 0000000..81b9584
--- /dev/null
+++ 
b/code/base/src/test/java/org/apache/tamaya/base/convert/BigDecimalConverter.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.base.convert;
+
+import javax.config.spi.Converter;
+import java.math.BigDecimal;
+
+/**
+ * Simple converter for BigDecimal.
+ */
+public class BigDecimalConverter implements Converter<BigDecimal> {
+    @Override
+    public BigDecimal convert(String s) {
+        return new BigDecimal(s);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/base/src/test/java/org/apache/tamaya/base/convert/DoubleConverter.java
----------------------------------------------------------------------
diff --git 
a/code/base/src/test/java/org/apache/tamaya/base/convert/DoubleConverter.java 
b/code/base/src/test/java/org/apache/tamaya/base/convert/DoubleConverter.java
new file mode 100644
index 0000000..98709b1
--- /dev/null
+++ 
b/code/base/src/test/java/org/apache/tamaya/base/convert/DoubleConverter.java
@@ -0,0 +1,31 @@
+/*
+ * 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.base.convert;
+
+import javax.config.spi.Converter;
+
+/**
+ * Simple converter for Double.
+ */
+public class DoubleConverter implements Converter<Double> {
+    @Override
+    public Double convert(String s) {
+        return Double.valueOf(s);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/base/src/test/java/org/apache/tamaya/base/convert/IntConverter.java
----------------------------------------------------------------------
diff --git 
a/code/base/src/test/java/org/apache/tamaya/base/convert/IntConverter.java 
b/code/base/src/test/java/org/apache/tamaya/base/convert/IntConverter.java
new file mode 100644
index 0000000..950e3a7
--- /dev/null
+++ b/code/base/src/test/java/org/apache/tamaya/base/convert/IntConverter.java
@@ -0,0 +1,31 @@
+/*
+ * 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.base.convert;
+
+import javax.config.spi.Converter;
+
+/**
+ * Simple converter for Integer.
+ */
+public class IntConverter implements Converter<Integer> {
+    @Override
+    public Integer convert(String s) {
+        return Integer.valueOf(s);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/base/src/test/resources/META-INF/services/javax.config.spi.Converter
----------------------------------------------------------------------
diff --git 
a/code/base/src/test/resources/META-INF/services/javax.config.spi.Converter 
b/code/base/src/test/resources/META-INF/services/javax.config.spi.Converter
index 30fb5d6..2acf11c 100644
--- a/code/base/src/test/resources/META-INF/services/javax.config.spi.Converter
+++ b/code/base/src/test/resources/META-INF/services/javax.config.spi.Converter
@@ -16,4 +16,7 @@
 # specific language governing permissions and limitations
 # under the License.
 #
-org.apache.tamaya.base.convert.CTestConverter
\ No newline at end of file
+org.apache.tamaya.base.convert.CTestConverter
+org.apache.tamaya.base.convert.IntConverter
+org.apache.tamaya.base.convert.DoubleConverter
+org.apache.tamaya.base.convert.BigDecimalConverter
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/core/bnd.bnd
----------------------------------------------------------------------
diff --git a/code/core/bnd.bnd b/code/core/bnd.bnd
index ff0a686..7970af0 100644
--- a/code/core/bnd.bnd
+++ b/code/core/bnd.bnd
@@ -9,6 +9,7 @@
 javac.source: 1.8
 javac.target: 1.8
 
+Automatic-Module-Name: org.apache.tamaya.core
 Bundle-Version: ${version}.${tstamp}
 Bundle-Name: Apache Tamaya - Core
 Bundle-SymbolicName: org.apache.tamaya.core

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/core/src/main/java/org/apache/tamaya/core/converters/BigIntegerConverter.java
----------------------------------------------------------------------
diff --git 
a/code/core/src/main/java/org/apache/tamaya/core/converters/BigIntegerConverter.java
 
b/code/core/src/main/java/org/apache/tamaya/core/converters/BigIntegerConverter.java
index 9dc6f8a..be41764 100644
--- 
a/code/core/src/main/java/org/apache/tamaya/core/converters/BigIntegerConverter.java
+++ 
b/code/core/src/main/java/org/apache/tamaya/core/converters/BigIntegerConverter.java
@@ -98,7 +98,7 @@ public class BigIntegerConverter implements 
Converter<BigInteger> {
 
     @Override
     public boolean equals(Object o){
-        return getClass().equals(o.getClass());
+        return Objects.nonNull(o) && getClass().equals(o.getClass());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/core/src/main/java/org/apache/tamaya/core/converters/ByteConverter.java
----------------------------------------------------------------------
diff --git 
a/code/core/src/main/java/org/apache/tamaya/core/converters/ByteConverter.java 
b/code/core/src/main/java/org/apache/tamaya/core/converters/ByteConverter.java
index 8d5c450..6289d6a 100644
--- 
a/code/core/src/main/java/org/apache/tamaya/core/converters/ByteConverter.java
+++ 
b/code/core/src/main/java/org/apache/tamaya/core/converters/ByteConverter.java
@@ -76,7 +76,7 @@ public class ByteConverter implements Converter<Byte> {
 
     @Override
     public boolean equals(Object o){
-        return getClass().equals(o.getClass());
+        return Objects.nonNull(o) && getClass().equals(o.getClass());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/core/src/main/java/org/apache/tamaya/core/converters/CharConverter.java
----------------------------------------------------------------------
diff --git 
a/code/core/src/main/java/org/apache/tamaya/core/converters/CharConverter.java 
b/code/core/src/main/java/org/apache/tamaya/core/converters/CharConverter.java
index 1c3c678..2b2cae9 100644
--- 
a/code/core/src/main/java/org/apache/tamaya/core/converters/CharConverter.java
+++ 
b/code/core/src/main/java/org/apache/tamaya/core/converters/CharConverter.java
@@ -73,7 +73,7 @@ public class CharConverter implements Converter<Character> {
 
     @Override
     public boolean equals(Object o){
-        return getClass().equals(o.getClass());
+        return Objects.nonNull(o) && getClass().equals(o.getClass());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/core/src/main/java/org/apache/tamaya/core/converters/DoubleConverter.java
----------------------------------------------------------------------
diff --git 
a/code/core/src/main/java/org/apache/tamaya/core/converters/DoubleConverter.java
 
b/code/core/src/main/java/org/apache/tamaya/core/converters/DoubleConverter.java
index c3dc9b3..dbac0bc 100644
--- 
a/code/core/src/main/java/org/apache/tamaya/core/converters/DoubleConverter.java
+++ 
b/code/core/src/main/java/org/apache/tamaya/core/converters/DoubleConverter.java
@@ -86,7 +86,7 @@ public class DoubleConverter implements Converter<Double> {
 
     @Override
     public boolean equals(Object o){
-        return getClass().equals(o.getClass());
+        return Objects.nonNull(o) && getClass().equals(o.getClass());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/core/src/main/java/org/apache/tamaya/core/converters/FileConverter.java
----------------------------------------------------------------------
diff --git 
a/code/core/src/main/java/org/apache/tamaya/core/converters/FileConverter.java 
b/code/core/src/main/java/org/apache/tamaya/core/converters/FileConverter.java
index a9796f8..82f2bab 100644
--- 
a/code/core/src/main/java/org/apache/tamaya/core/converters/FileConverter.java
+++ 
b/code/core/src/main/java/org/apache/tamaya/core/converters/FileConverter.java
@@ -55,7 +55,7 @@ public class FileConverter implements Converter<File> {
 
     @Override
     public boolean equals(Object o){
-        return getClass().equals(o.getClass());
+        return Objects.nonNull(o) && getClass().equals(o.getClass());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/core/src/main/java/org/apache/tamaya/core/converters/LongConverter.java
----------------------------------------------------------------------
diff --git 
a/code/core/src/main/java/org/apache/tamaya/core/converters/LongConverter.java 
b/code/core/src/main/java/org/apache/tamaya/core/converters/LongConverter.java
index 11b0a18..3372468 100644
--- 
a/code/core/src/main/java/org/apache/tamaya/core/converters/LongConverter.java
+++ 
b/code/core/src/main/java/org/apache/tamaya/core/converters/LongConverter.java
@@ -76,7 +76,7 @@ public class LongConverter implements Converter<Long> {
 
     @Override
     public boolean equals(Object o){
-        return getClass().equals(o.getClass());
+        return Objects.nonNull(o) && getClass().equals(o.getClass());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/core/src/main/java/org/apache/tamaya/core/converters/NumberConverter.java
----------------------------------------------------------------------
diff --git 
a/code/core/src/main/java/org/apache/tamaya/core/converters/NumberConverter.java
 
b/code/core/src/main/java/org/apache/tamaya/core/converters/NumberConverter.java
index a1d41b1..8546e97 100644
--- 
a/code/core/src/main/java/org/apache/tamaya/core/converters/NumberConverter.java
+++ 
b/code/core/src/main/java/org/apache/tamaya/core/converters/NumberConverter.java
@@ -77,7 +77,7 @@ public class NumberConverter implements Converter<Number> {
 
     @Override
     public boolean equals(Object o){
-        return getClass().equals(o.getClass());
+        return Objects.nonNull(o) && getClass().equals(o.getClass());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/core/src/test/java/org/apache/tamaya/core/internal/converters/BigDecimalConverterTest.java
----------------------------------------------------------------------
diff --git 
a/code/core/src/test/java/org/apache/tamaya/core/internal/converters/BigDecimalConverterTest.java
 
b/code/core/src/test/java/org/apache/tamaya/core/internal/converters/BigDecimalConverterTest.java
index 608e29f..da3b99e 100644
--- 
a/code/core/src/test/java/org/apache/tamaya/core/internal/converters/BigDecimalConverterTest.java
+++ 
b/code/core/src/test/java/org/apache/tamaya/core/internal/converters/BigDecimalConverterTest.java
@@ -22,6 +22,7 @@ package org.apache.tamaya.core.internal.converters;
 
 import org.apache.tamaya.base.convert.ConversionContext;
 import org.apache.tamaya.core.converters.BigDecimalConverter;
+import org.apache.tamaya.core.converters.BigIntegerConverter;
 import org.junit.Test;
 
 import javax.config.Config;
@@ -133,4 +134,12 @@ public class BigDecimalConverterTest {
                ConversionContext.reset();
                assertThat(value).isNull();
        }
-}
\ No newline at end of file
+
+    @Test
+    public void testEquality() throws Exception {
+        BigDecimalConverter converter = new BigDecimalConverter();
+
+        assertThat(converter).isEqualTo(new BigDecimalConverter());
+        assertThat(converter).isNotEqualTo(new BigIntegerConverter());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/old/api/bnd.bnd
----------------------------------------------------------------------
diff --git a/code/old/api/bnd.bnd b/code/old/api/bnd.bnd
index b606a72..97f65cc 100644
--- a/code/old/api/bnd.bnd
+++ b/code/old/api/bnd.bnd
@@ -9,6 +9,7 @@
 javac.source: 1.8
 javac.target: 1.8
 
+Automatic-Module-Name: org.apache.tamaya
 Bundle-Version: ${version}.${tstamp}
 Bundle-SymbolicName: org.apache.tamaya
 Bundle-Name: Apache Tamaya - API

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/BigDecimalConverter.java
----------------------------------------------------------------------
diff --git 
a/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/BigDecimalConverter.java
 
b/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/BigDecimalConverter.java
index 7e71b7e..648f8bc 100644
--- 
a/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/BigDecimalConverter.java
+++ 
b/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/BigDecimalConverter.java
@@ -66,7 +66,7 @@ public class BigDecimalConverter implements 
PropertyConverter<BigDecimal>{
 
     @Override
     public boolean equals(Object o){
-        return getClass().equals(o.getClass());
+        return Objects.nonNull(o) && getClass().equals(o.getClass());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/BooleanConverter.java
----------------------------------------------------------------------
diff --git 
a/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/BooleanConverter.java
 
b/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/BooleanConverter.java
index 7e61140..1f0a128 100644
--- 
a/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/BooleanConverter.java
+++ 
b/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/BooleanConverter.java
@@ -63,7 +63,7 @@ public class BooleanConverter implements 
PropertyConverter<Boolean> {
 
     @Override
     public boolean equals(Object o){
-        return getClass().equals(o.getClass());
+        return Objects.nonNull(o) && getClass().equals(o.getClass());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/ClassConverter.java
----------------------------------------------------------------------
diff --git 
a/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/ClassConverter.java
 
b/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/ClassConverter.java
index b29bc15..7be9ec2 100644
--- 
a/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/ClassConverter.java
+++ 
b/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/ClassConverter.java
@@ -68,7 +68,7 @@ public class ClassConverter implements 
PropertyConverter<Class<?>>{
 
     @Override
     public boolean equals(Object o){
-        return getClass().equals(o.getClass());
+        return Objects.nonNull(o) && getClass().equals(o.getClass());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/CurrencyConverter.java
----------------------------------------------------------------------
diff --git 
a/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/CurrencyConverter.java
 
b/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/CurrencyConverter.java
index b769d06..15e10e0 100644
--- 
a/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/CurrencyConverter.java
+++ 
b/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/CurrencyConverter.java
@@ -92,7 +92,7 @@ public class CurrencyConverter implements 
PropertyConverter<Currency> {
 
     @Override
     public boolean equals(Object o){
-        return getClass().equals(o.getClass());
+        return Objects.nonNull(o) && getClass().equals(o.getClass());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/DurationConverter.java
----------------------------------------------------------------------
diff --git 
a/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/DurationConverter.java
 
b/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/DurationConverter.java
index f258186..84fb184 100644
--- 
a/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/DurationConverter.java
+++ 
b/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/DurationConverter.java
@@ -24,6 +24,7 @@ import org.osgi.service.component.annotations.Component;
 
 import java.time.Duration;
 import java.time.temporal.ChronoUnit;
+import java.util.Objects;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -49,7 +50,7 @@ public class DurationConverter implements 
PropertyConverter<Duration> {
 
     @Override
     public boolean equals(Object o){
-        return getClass().equals(o.getClass());
+        return Objects.nonNull(o) && getClass().equals(o.getClass());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/IntegerConverter.java
----------------------------------------------------------------------
diff --git 
a/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/IntegerConverter.java
 
b/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/IntegerConverter.java
index d09df9b..ea3e6ea 100644
--- 
a/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/IntegerConverter.java
+++ 
b/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/IntegerConverter.java
@@ -76,7 +76,7 @@ public class IntegerConverter implements 
PropertyConverter<Integer>{
 
     @Override
     public boolean equals(Object o){
-        return getClass().equals(o.getClass());
+        return Objects.nonNull(o) && getClass().equals(o.getClass());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/ShortConverter.java
----------------------------------------------------------------------
diff --git 
a/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/ShortConverter.java
 
b/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/ShortConverter.java
index 7b561f3..beda7e7 100644
--- 
a/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/ShortConverter.java
+++ 
b/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/ShortConverter.java
@@ -73,7 +73,7 @@ public class ShortConverter implements 
PropertyConverter<Short>{
 
     @Override
     public boolean equals(Object o){
-        return getClass().equals(o.getClass());
+        return Objects.nonNull(o) && getClass().equals(o.getClass());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/7bf83f0b/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/URIConverter.java
----------------------------------------------------------------------
diff --git 
a/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/URIConverter.java
 
b/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/URIConverter.java
index 793631e..2e653f2 100644
--- 
a/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/URIConverter.java
+++ 
b/code/old/core/src/main/java/org/apache/tamaya/core/internal/converters/URIConverter.java
@@ -52,7 +52,7 @@ public class URIConverter implements PropertyConverter<URI> {
 
     @Override
     public boolean equals(Object o){
-        return getClass().equals(o.getClass());
+        return Objects.nonNull(o) && getClass().equals(o.getClass());
     }
 
     @Override

Reply via email to