tamaya-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From anat...@apache.org
Subject incubator-tamaya git commit: TAMAYA-30: - Clarified some aspects regarding Codecs and type conversion in ConfigChangeSet. - Fixed bug in Codecs (should throw ConfigException when a Codec is missing).
Date Sat, 20 Dec 2014 23:04:54 GMT
Repository: incubator-tamaya
Updated Branches:
  refs/heads/master 1db383ffc -> 3927cda65


TAMAYA-30:
- Clarified some aspects regarding Codecs and type conversion in ConfigChangeSet.
- Fixed bug in Codecs (should throw ConfigException when a Codec is missing).


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

Branch: refs/heads/master
Commit: 3927cda65806b0f537c4a2016173a004e8ed6938
Parents: 1db383f
Author: anatole <anatole@apache.org>
Authored: Sun Dec 21 00:04:44 2014 +0100
Committer: anatole <anatole@apache.org>
Committed: Sun Dec 21 00:04:44 2014 +0100

----------------------------------------------------------------------
 .../java/org/apache/tamaya/ConfigChangeSet.java |  27 +-
 .../apache/tamaya/ConfigChangeSetBuilder.java   | 257 ++++++++++++++-----
 .../properties/DefaultCodecsSingletonSpi.java   |  10 +-
 3 files changed, 212 insertions(+), 82 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/3927cda6/api/src/main/java/org/apache/tamaya/ConfigChangeSet.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/ConfigChangeSet.java b/api/src/main/java/org/apache/tamaya/ConfigChangeSet.java
index 7beab65..4ff02ca 100644
--- a/api/src/main/java/org/apache/tamaya/ConfigChangeSet.java
+++ b/api/src/main/java/org/apache/tamaya/ConfigChangeSet.java
@@ -30,7 +30,7 @@ import java.util.*;
  */
 public final class ConfigChangeSet {
     /** The base property provider/configuration. */
-    private PropertySource propertyProvider;
+    private PropertySource propertySource;
     /** The base version, usable for optimistic locking. */
     private String baseVersion;
     /** The recorded changes. */
@@ -47,12 +47,12 @@ public final class ConfigChangeSet {
 
     /**
      * Constructor used by {@link ConfigChangeSetBuilder}.
-     * @param propertyProvider The base property provider/configuration, not null.
+     * @param propertySource The base property provider/configuration, not null.
      * @param baseVersion The base version, usable for optimistic locking.
      * @param changes The recorded changes, not null.
      */
-    ConfigChangeSet(PropertySource propertyProvider, String baseVersion, Collection<PropertyChangeEvent>
changes) {
-        this.propertyProvider = Objects.requireNonNull(propertyProvider);
+    ConfigChangeSet(PropertySource propertySource, String baseVersion, Collection<PropertyChangeEvent>
changes) {
+        this.propertySource = Objects.requireNonNull(propertySource);
         this.baseVersion = baseVersion;
         changes.forEach((c) -> this.changes.put(c.getPropertyName(), c));
     }
@@ -62,7 +62,7 @@ public final class ConfigChangeSet {
      * @return the underlying property provider/configuration, never null.
      */
     public PropertySource getPropertySource(){
-        return this.propertyProvider;
+        return this.propertySource;
     }
 
     /**
@@ -154,26 +154,11 @@ public final class ConfigChangeSet {
         return this.changes.isEmpty();
     }
 
-    /**
-     * Applies all changes to the given map instance.
-     * @param map the target map.never null.
-     */
-    public void applyChangesTo(Map<String, String> map) {
-        for(Map.Entry<String,PropertyChangeEvent> en: this.changes.entrySet()){
-            if(en.getValue().getNewValue() == null){
-                map.remove(en.getKey());
-            }
-            else{
-                map.put(en.getKey(), (String)en.getValue().getNewValue());
-            }
-        }
-    }
-
 
     @Override
     public String toString() {
         return "ConfigChangeSet{" +
-                "properties=" + propertyProvider +
+                "properties=" + propertySource +
                 ", baseVersion=" + baseVersion +
                 ", changes=" + changes +
                 '}';

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/3927cda6/api/src/main/java/org/apache/tamaya/ConfigChangeSetBuilder.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/ConfigChangeSetBuilder.java b/api/src/main/java/org/apache/tamaya/ConfigChangeSetBuilder.java
index 28c1810..9cd81b5 100644
--- a/api/src/main/java/org/apache/tamaya/ConfigChangeSetBuilder.java
+++ b/api/src/main/java/org/apache/tamaya/ConfigChangeSetBuilder.java
@@ -21,77 +21,123 @@ package org.apache.tamaya;
 import java.beans.PropertyChangeEvent;
 import java.time.Instant;
 import java.util.*;
+import java.util.function.Function;
 
 /**
  * Models a set current changes to be applied to a configuration/property provider.  Such
a set can be applied
  * to any {@link PropertySource} instance. If the provider is mutable it may check the
  * version given and applyChanges the changes to the provider/configuration, including triggering
current regarding
  * change events.
- *
- * Created by Anatole on 06.09.2014.
+ * <p>
+ * For appropriate conversion a {@code Function<String, Codec>} can be applied, which
performs correct conversion,
+ * when changed values are set. This function enables connecting e.g. setters on a configuration
template with
+ * the corresponding conversion logic, so the template calls are correctly converted back.
  */
 public final class ConfigChangeSetBuilder {
-    /** The recorded changes. */
+    /**
+     * The recorded changes.
+     */
     final SortedMap<String, PropertyChangeEvent> delta = new TreeMap<>();
-    /** The underlying configuration/provider. */
+    /**
+     * The underlying configuration/provider.
+     */
     PropertySource source;
-    /** The base version, if any. Used for optimistic version checking. */
+    /**
+     * The base version, if any. Used for optimistic version checking.
+     */
     String baseVersion;
+    /**
+     * Codesc provider, or null.
+     */
+    Function<String, Codec> codecs;
 
     /**
      * Constructor.
-     * @param source the underlying configuration/provider, not null.
+     *
+     * @param source      the underlying configuration/provider, not null.
      * @param baseVersion the base version, used for optimistic version checking.
+     * @param codecs      function to provide customized codecs, when according values are
changed, if not set the
+     *                    default codecs provided by {@link Codec#getInstance(Class)} are
used.
      */
-    private ConfigChangeSetBuilder(PropertySource source, String baseVersion) {
-        Objects.requireNonNull(source);
-        this.source = source;
-        this.baseVersion= baseVersion;
+    private ConfigChangeSetBuilder(PropertySource source, String baseVersion, Function<String,
Codec> codecs) {
+        this.source = Objects.requireNonNull(source);
+        this.baseVersion = baseVersion;
+        this.codecs = codecs;
     }
 
     /**
      * Creates a new instance current this builder.
+     *
      * @param source the underlying property provider/configuration, not null.
      * @return the builder for chaining.
      */
     public static ConfigChangeSetBuilder of(PropertySource source) {
-        return new ConfigChangeSetBuilder(source, Instant.now().toString());
+        return new ConfigChangeSetBuilder(source, Instant.now().toString(), null);
     }
 
     /**
      * Creates a new instance current this builder.
+     *
      * @param source the underlying property provider/configuration, not null.
+     * @param codecs function to provide customized codecs, when according values are changed,
if not set the
+     *               default codecs provided by {@link Codec#getInstance(Class)} are used.
+     * @return the builder for chaining.
+     */
+    public static ConfigChangeSetBuilder of(PropertySource source, Function<String, Codec>
codecs) {
+        return new ConfigChangeSetBuilder(source, Instant.now().toString(), codecs);
+    }
+
+    /**
+     * Creates a new instance current this builder.
+     *
+     * @param source      the underlying property provider/configuration, not null.
      * @param baseVersion the base version to be used.
      * @return the builder for chaining.
      */
     public static ConfigChangeSetBuilder of(PropertySource source, String baseVersion) {
-        return new ConfigChangeSetBuilder(source, baseVersion);
+        return new ConfigChangeSetBuilder(source, baseVersion, null);
     }
 
     /**
      * Creates a new instance current this builder.
+     *
+     * @param source      the underlying property provider/configuration, not null.
+     * @param baseVersion the base version to be used.
+     * @param codecs      function to provide customized codecs, when according values are
changed, if not set the
+     *                    default codecs provided by {@link Codec#getInstance(Class)} are
used.
+     * @return the builder for chaining.
+     */
+    public static ConfigChangeSetBuilder of(PropertySource source, String baseVersion, Function<String,
Codec> codecs) {
+        return new ConfigChangeSetBuilder(source, baseVersion, codecs);
+    }
+
+    /**
+     * Creates a new instance current this builder.
+     *
      * @param configuration the base configuration, not null.
      * @return the builder for chaining.
      */
     public static ConfigChangeSetBuilder of(Configuration configuration) {
-        return new ConfigChangeSetBuilder(configuration, configuration.getVersion());
+        return new ConfigChangeSetBuilder(configuration, configuration.getVersion(), null);
     }
 
     /**
-     * Add a change as a {@link java.beans.PropertyChangeEvent}.
-     * @param changeEvent the change event.
+     * Creates a new instance current this builder.
+     *
+     * @param configuration the base configuration, not null.
+     * @param codecs        function to provide customized codecs, when according values
are changed, if not set the
+     *                      default codecs provided by {@link Codec#getInstance(Class)} are
used.
      * @return the builder for chaining.
      */
-    public ConfigChangeSetBuilder addChange(PropertyChangeEvent changeEvent) {
-        Objects.requireNonNull(changeEvent);
-        // todo consider any codecs
-        this.delta.put(changeEvent.getPropertyName(), changeEvent);
-        return this;
+    public static ConfigChangeSetBuilder of(Configuration configuration, Function<String,
Codec> codecs) {
+        return new ConfigChangeSetBuilder(configuration, configuration.getVersion(), codecs);
     }
 
+
     /**
      * This method records all changes to be applied to the base property provider/configuration
to
      * achieve the given target state.
+     *
      * @param newState the new target state, not null.
      * @return the builder for chaining.
      */
@@ -102,32 +148,34 @@ public final class ConfigChangeSetBuilder {
 
     /**
      * Get the current values, also considering any changes recorded within this change set.
+     *
      * @param key the key current the entry, not null.
      * @return the keys, or null.
      */
     public String get(String key) {
         PropertyChangeEvent change = this.delta.get(key);
-        if(change!=null && !(change.getNewValue()==null)){
-            return (String)change.getNewValue();
+        if (change != null && !(change.getNewValue() == null)) {
+            return (String) change.getNewValue();
         }
         return null;
     }
 
     /**
      * Marks the given key(s) fromMap the configuration/properties to be removed.
-     * @param key the key current the entry, not null.
+     *
+     * @param key       the key current the entry, not null.
      * @param otherKeys additional keys to be removed (convenience), not null.
      * @return the builder for chaining.
      */
     public ConfigChangeSetBuilder remove(String key, String... otherKeys) {
         String oldValue = this.source.get(key).orElse(null);
-        if(oldValue==null){
+        if (oldValue == null) {
             this.delta.remove(key);
         }
         this.delta.put(key, new PropertyChangeEvent(this.source, key, oldValue, null));
-        for(String addKey:otherKeys){
+        for (String addKey : otherKeys) {
             oldValue = this.source.get(addKey).orElse(null);
-            if(oldValue==null){
+            if (oldValue == null) {
                 this.delta.remove(addKey);
             }
             this.delta.put(addKey, new PropertyChangeEvent(this.source, addKey, oldValue,
null));
@@ -137,143 +185,235 @@ public final class ConfigChangeSetBuilder {
 
     /**
      * Applies the given keys.
-     * @param key the key current the entry, not null.
+     *
+     * @param key   the key current the entry, not null.
      * @param value the keys to be applied, not null.
      * @return the builder for chaining.
      */
     public ConfigChangeSetBuilder put(String key, boolean value) {
-        this.delta.put(key, new PropertyChangeEvent(this.source, key, this.source.get(key).orElse(null),
Objects.requireNonNull(value).toString()));
+        Codec<Boolean> codec = this.codecs != null ? this.codecs.apply(key) : null;
+        if (codec == null) codec = Codec.getInstance(Boolean.class);
+        this.delta.put(key, new PropertyChangeEvent(this.source, key, this.source.get(key).orElse(null),
codec.serialize(value)));
         return this;
     }
 
     /**
      * Applies the given keys.
-     * @param key the key current the entry, not null.
+     *
+     * @param key   the key current the entry, not null.
      * @param value the keys to be applied, not null.
      * @return the builder for chaining.
      */
     public ConfigChangeSetBuilder put(String key, byte value) {
-        this.delta.put(key, new PropertyChangeEvent(this.source, key, this.source.get(key).orElse(null),
Objects.requireNonNull(value).toString()));
+        Codec<Byte> codec = this.codecs != null ? this.codecs.apply(key) : null;
+        if (codec == null) codec = Codec.getInstance(Byte.class);
+        this.delta.put(key, new PropertyChangeEvent(this.source, key, this.source.get(key).orElse(null),
codec.serialize(value)));
         return this;
     }
 
     /**
      * Applies the given keys.
-     * @param key the key current the entry, not null.
+     *
+     * @param key   the key current the entry, not null.
      * @param value the keys to be applied, not null.
      * @return the builder for chaining.
      */
     public ConfigChangeSetBuilder put(String key, char value) {
-        this.delta.put(key, new PropertyChangeEvent(this.source, key, this.source.get(key).orElse(null),
Objects.requireNonNull(value).toString()));
+        Codec<Character> codec = this.codecs != null ? this.codecs.apply(key) : null;
+        if (codec == null) codec = Codec.getInstance(Character.class);
+        this.delta.put(key, new PropertyChangeEvent(this.source, key, this.source.get(key).orElse(null),
codec.serialize(value)));
         return this;
     }
 
     /**
      * Applies the given keys.
-     * @param key the key current the entry, not null.
+     *
+     * @param key   the key current the entry, not null.
      * @param value the keys to be applied, not null.
      * @return the builder for chaining.
      */
     public ConfigChangeSetBuilder put(String key, short value) {
-        this.delta.put(key, new PropertyChangeEvent(this.source, key, this.source.get(key).orElse(null),
Objects.requireNonNull(value).toString()));
+        Codec<Short> codec = this.codecs != null ? this.codecs.apply(key) : null;
+        if (codec == null) codec = Codec.getInstance(Short.class);
+        this.delta.put(key, new PropertyChangeEvent(this.source, key, this.source.get(key).orElse(null),
codec.serialize(value)));
         return this;
     }
 
     /**
      * Applies the given keys.
-     * @param key the key current the entry, not null.
+     *
+     * @param key   the key current the entry, not null.
      * @param value the keys to be applied, not null.
      * @return the builder for chaining.
      */
     public ConfigChangeSetBuilder put(String key, int value) {
-        this.delta.put(key, new PropertyChangeEvent(this.source, key, this.source.get(key).orElse(null),
Objects.requireNonNull(value).toString()));
+        Codec<Integer> codec = this.codecs != null ? this.codecs.apply(key) : null;
+        if (codec == null) codec = Codec.getInstance(Integer.class);
+        this.delta.put(key, new PropertyChangeEvent(this.source, key, this.source.get(key).orElse(null),
codec.serialize(value)));
         return this;
     }
 
     /**
      * Applies the given keys.
-     * @param key the key current the entry, not null.
+     *
+     * @param key   the key current the entry, not null.
      * @param value the keys to be applied, not null.
      * @return the builder for chaining.
      */
     public ConfigChangeSetBuilder put(String key, long value) {
-        this.delta.put(key, new PropertyChangeEvent(this.source, key, this.source.get(key).orElse(null),
Objects.requireNonNull(value).toString()));
+        Codec<Long> codec = this.codecs != null ? this.codecs.apply(key) : null;
+        if (codec == null) codec = Codec.getInstance(Long.class);
+        this.delta.put(key, new PropertyChangeEvent(this.source, key, this.source.get(key).orElse(null),
codec.serialize(value)));
         return this;
     }
 
     /**
      * Applies the given keys.
-     * @param key the key current the entry, not null.
+     *
+     * @param key   the key current the entry, not null.
      * @param value the keys to be applied, not null.
      * @return the builder for chaining.
      */
     public ConfigChangeSetBuilder put(String key, float value) {
-        this.delta.put(key, new PropertyChangeEvent(this.source, key, this.source.get(key).orElse(null),
Objects.requireNonNull(value).toString()));
+        Codec<Float> codec = this.codecs != null ? this.codecs.apply(key) : null;
+        if (codec == null) codec = Codec.getInstance(Float.class);
+        this.delta.put(key, new PropertyChangeEvent(this.source, key, this.source.get(key).orElse(null),
codec.serialize(value)));
         return this;
     }
 
     /**
      * Applies the given keys.
-     * @param key the key current the entry, not null.
+     *
+     * @param key   the key current the entry, not null.
      * @param value the keys to be applied, not null.
      * @return the builder for chaining.
      */
     public ConfigChangeSetBuilder put(String key, double value) {
-        this.delta.put(key, new PropertyChangeEvent(this.source, key, this.source.get(key).orElse(null),
Objects.requireNonNull(value).toString()));
+        Codec<Double> codec = this.codecs != null ? this.codecs.apply(key) : null;
+        if (codec == null) codec = Codec.getInstance(Double.class);
+        this.delta.put(key, new PropertyChangeEvent(this.source, key, this.source.get(key).orElse(null),
codec.serialize(value)));
         return this;
     }
 
+
     /**
      * Applies the given keys.
-     * @param key the key current the entry, not null.
+     *
+     * @param key   the key current the entry, not null.
+     * @param value the keys to be applied, not null.
+     * @return the builder for chaining.
+     */
+    public ConfigChangeSetBuilder put(String key, String value) {
+        Codec<String> codec = this.codecs != null ? this.codecs.apply(key) : null;
+        this.delta.put(key, new PropertyChangeEvent(this.source, key, this.source.get(key).orElse(null),
codec != null?codec.serialize(value):value));
+        return this;
+    }
+
+    /**
+     * Applies the given keys.
+     *
+     * @param key   the key current the entry, not null.
+     * @param value the keys to be applied, not null.
+     * @return the builder for chaining.
+     * @throws ConfigException if no matching Codec could be found.
+     */
+    public <T> ConfigChangeSetBuilder put(String key, Class<T> type, T value)
{
+        put(key, type, value, null);
+        return this;
+    }
+
+    /**
+     * Applies the given keys.
+     *
+     * @param key   the key current the entry, not null.
      * @param value the keys to be applied, not null.
+     * @param codec the codec to be used, if set overrides any other codecs that may apply.
If null an appropriate
+     *              codec is tried to be evaluated as needed.
+     * @return the builder for chaining.
+     * @throws ConfigException if no matching Codec could be found.
+     */
+    public <T> ConfigChangeSetBuilder put(String key, Class<T> type, T value,
Codec codec) {
+        Codec<T> targetCodec = codec;
+        if(targetCodec==null){
+            targetCodec = this.codecs != null ? this.codecs.apply(key) : null;
+        }
+        if (targetCodec == null){
+            targetCodec = Codec.getInstance(type);
+        }
+        this.delta.put(key, new PropertyChangeEvent(this.source, key, this.source.get(key).orElse(null),
targetCodec.serialize(Objects.requireNonNull(value))));
+        return this;
+    }
+
+    /**
+     * Apply all the given values to the base configuration/properties.
+     * Note that all values passed must be convertible to String, either
+     * <ul>
+     * <li>the registered codecs provider provides codecs for the corresponding keys,
or </li>
+     * <li>default codecs are present for the given type, or</li>
+     * <li>the value is an instanceof String</li>
+     * </ul>
+     *
+     * @param changes the changes to be applied, not null.
      * @return the builder for chaining.
      */
-    public ConfigChangeSetBuilder put(String key, Object value) {
-        this.delta.put(key, new PropertyChangeEvent(this.source, key, this.source.get(key).orElse(null),
Objects.requireNonNull(value).toString()));
+    public ConfigChangeSetBuilder putAll(Map<String, ?> changes) {
+        changes.forEach((k, v) ->
+                put(k, (Class) v.getClass(), v));
         return this;
     }
 
     /**
      * Apply all the given values to the base configuration/properties.
+     * Note that all values passed must be convertible to String, either
+     * <ul>
+     * <li>the registered codecs provider provides codecs for the corresponding keys,
or </li>
+     * <li>default codecs are present for the given type, or</li>
+     * <li>the value is an instanceof String</li>
+     * </ul>
+     *
      * @param changes the changes to be applied, not null.
+     * @param codecs      function to provide customized overriding codecs, when according
values are changed,
+     *                    if not set the default codecs are used.
      * @return the builder for chaining.
      */
-    public ConfigChangeSetBuilder putAll(Map<String,Object> changes) {
-        changes.forEach((k,v) ->
-                this.delta.put(k, new PropertyChangeEvent(this.source, k, this.source.get(k).orElse(null),
v)));
+    public ConfigChangeSetBuilder putAll(Map<String, ?> changes, Function<String,
Codec<?>> codecs) {
+        changes.forEach((k, v) ->
+                put(k, (Class) v.getClass(), v, codecs.apply(k)));
         return this;
     }
 
     /**
      * This method will create a change set that clears all entries fromMap the given base
configuration/properties.
+     *
      * @return the builder for chaining.
      */
-    public ConfigChangeSetBuilder clear() {
+    public ConfigChangeSetBuilder deleteAll() {
         this.delta.clear();
-        this.source.toMap().forEach((k,v) ->
+        this.source.toMap().forEach((k, v) ->
                 this.delta.put(k, new PropertyChangeEvent(this.source, k, v, null)));
         return this;
     }
 
     /**
      * Checks if the change set is empty, i.e. does not contain any changes.
+     *
      * @return true, if the set is empty.
      */
-    public boolean isEmpty(){
+    public boolean isEmpty() {
         return this.delta.isEmpty();
     }
 
     /**
-     * Resets this change set instance. This will clear all changes done to this set, so
the
+     * Resets this change set instance. This will clear all changes done to this builder,
so the
      * set will be empty.
      */
-    public void reset(){
+    public void reset() {
         this.delta.clear();
     }
 
     /**
      * Builds the corresponding change set.
+     *
      * @return the new change set, never null.
      */
     public ConfigChangeSet build() {
@@ -283,6 +423,7 @@ public final class ConfigChangeSetBuilder {
     /**
      * Compares the two property config/configurations and creates a collection current all
changes
      * that must be appied to render {@code map1} into {@code map2}.
+     *
      * @param map1 the source map, not null.
      * @param map2 the target map, not null.
      * @return a collection current change events, never null.
@@ -291,19 +432,17 @@ public final class ConfigChangeSetBuilder {
         List<PropertyChangeEvent> changes = new ArrayList<>();
         for (Map.Entry<String, String> en : map1.toMap().entrySet()) {
             Optional<String> val = map2.get(en.getKey());
-            if(!val.isPresent()) {
+            if (!val.isPresent()) {
                 changes.add(new PropertyChangeEvent(map1, en.getKey(), null, en.getValue()));
-            }
-            else if(!val.get().equals(en.getValue())){
+            } else if (!val.get().equals(en.getValue())) {
                 changes.add(new PropertyChangeEvent(map1, en.getKey(), val.get(), en.getValue()));
             }
         }
         for (Map.Entry<String, String> en : map2.toMap().entrySet()) {
             Optional<String> val = map1.get(en.getKey());
-            if(!val.isPresent()) {
+            if (!val.isPresent()) {
                 changes.add(new PropertyChangeEvent(map1, en.getKey(), null, en.getValue()));
-            }
-            else if(!val.equals(Optional.ofNullable(en.getValue()))) {
+            } else if (!val.equals(Optional.ofNullable(en.getValue()))) {
                 changes.add(new PropertyChangeEvent(map1, en.getKey(), val.get(), en.getValue()));
             }
         }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/3927cda6/core/src/main/java/org/apache/tamaya/core/internal/properties/DefaultCodecsSingletonSpi.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/properties/DefaultCodecsSingletonSpi.java
b/core/src/main/java/org/apache/tamaya/core/internal/properties/DefaultCodecsSingletonSpi.java
index 07959d2..2b64bea 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/properties/DefaultCodecsSingletonSpi.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/properties/DefaultCodecsSingletonSpi.java
@@ -28,6 +28,7 @@ import java.time.LocalTime;
 import java.time.ZoneId;
 import java.util.Currency;
 import java.util.Map;
+import java.util.Objects;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.Function;
 
@@ -53,17 +54,19 @@ public class DefaultCodecsSingletonSpi implements CodecsSingletonSpi {
     public DefaultCodecsSingletonSpi(){
         // Add default adapters
         register(char.class, (s) -> s.charAt(0), (ch) -> String.valueOf(ch));
-        register(int.class, Integer::parseInt, Object::toString);
         register(byte.class, Byte::parseByte, Object::toString);
         register(short.class, Short::parseShort, Object::toString);
+        register(int.class, Integer::parseInt, Object::toString);
+        register(long.class, Long::parseLong, Object::toString);
         register(boolean.class, Boolean::parseBoolean, b -> String.valueOf(b));
         register(float.class, Float::parseFloat, f -> String.valueOf(f));
         register(double.class, Double::parseDouble, d -> String.valueOf(d));
 
         register(Character.class, (s) -> s.charAt(0), Object::toString);
-        register(Integer.class, Integer::valueOf, Object::toString);
         register(Byte.class, Byte::valueOf, Object::toString);
         register(Short.class, Short::valueOf, String::valueOf);
+        register(Integer.class, Integer::valueOf, Object::toString);
+        register(Long.class, Long::valueOf, Object::toString);
         register(Boolean.class, Boolean::valueOf, b -> String.valueOf(b));
         register(Float.class, Float::valueOf, f -> String.valueOf(f));
         register(Double.class, Double::valueOf, d -> String.valueOf(d));
@@ -104,6 +107,9 @@ public class DefaultCodecsSingletonSpi implements CodecsSingletonSpi {
         if(codec == null){
             codec = getDefaultCodec(targetType);
         }
+        if(codec == null){
+            throw new ConfigException("No Codec found for " + targetType.getName());
+        }
         return codec;
     }
 


Mime
View raw message