You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by jo...@apache.org on 2017/12/24 03:52:02 UTC

svn commit: r1819198 - in /geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config: ConfigImpl.java ConfigValueImpl.java DefaultConfigBuilder.java converters/MicroProfileTypedConverter.java

Author: johndament
Date: Sun Dec 24 03:52:02 2017
New Revision: 1819198

URL: http://svn.apache.org/viewvc?rev=1819198&view=rev
Log:
GERONIMO-6597 Adding support for programmatic registration of converters

Added:
    geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/converters/MicroProfileTypedConverter.java
Modified:
    geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java
    geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/ConfigValueImpl.java
    geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/DefaultConfigBuilder.java

Modified: geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java
URL: http://svn.apache.org/viewvc/geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java?rev=1819198&r1=1819197&r2=1819198&view=diff
==============================================================================
--- geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java (original)
+++ geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java Sun Dec 24 03:52:02 2017
@@ -16,17 +16,16 @@
  */
 package org.apache.geronimo.config;
 
+import org.apache.geronimo.config.converters.ImplicitConverter;
+import org.apache.geronimo.config.converters.MicroProfileTypedConverter;
+import org.eclipse.microprofile.config.Config;
+import org.eclipse.microprofile.config.spi.ConfigSource;
+import org.eclipse.microprofile.config.spi.Converter;
+
+import javax.enterprise.inject.Typed;
+import javax.enterprise.inject.Vetoed;
 import java.lang.reflect.Array;
-import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
-import java.net.URL;
-import java.time.Duration;
-import java.time.Instant;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.OffsetDateTime;
-import java.time.OffsetTime;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -40,30 +39,6 @@ import java.util.logging.Logger;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
-import org.apache.geronimo.config.converters.BooleanConverter;
-import org.apache.geronimo.config.converters.ClassConverter;
-import org.apache.geronimo.config.converters.DoubleConverter;
-import org.apache.geronimo.config.converters.DurationConverter;
-import org.apache.geronimo.config.converters.FloatConverter;
-import org.apache.geronimo.config.converters.ImplicitConverter;
-import org.apache.geronimo.config.converters.InstantConverter;
-import org.apache.geronimo.config.converters.IntegerConverter;
-import org.apache.geronimo.config.converters.LocalDateConverter;
-import org.apache.geronimo.config.converters.LocalDateTimeConverter;
-import org.apache.geronimo.config.converters.LocalTimeConverter;
-import org.apache.geronimo.config.converters.LongConverter;
-import org.apache.geronimo.config.converters.OffsetDateTimeConverter;
-import org.apache.geronimo.config.converters.OffsetTimeConverter;
-import org.apache.geronimo.config.converters.StringConverter;
-import org.apache.geronimo.config.converters.URLConverter;
-import org.eclipse.microprofile.config.Config;
-import org.eclipse.microprofile.config.spi.ConfigSource;
-import org.eclipse.microprofile.config.spi.Converter;
-
-import javax.annotation.Priority;
-import javax.enterprise.inject.Typed;
-import javax.enterprise.inject.Vetoed;
-
 /**
  * @author <a href="mailto:struberg@apache.org">Mark Struberg</a>
  * @author <a href="mailto:johndament@apache.org">John D. Ament</a>
@@ -74,40 +49,10 @@ public class ConfigImpl implements Confi
     protected Logger logger = Logger.getLogger(ConfigImpl.class.getName());
 
     protected final List<ConfigSource> configSources = new ArrayList<>();
-    protected final Map<Type, Converter> converters = new HashMap<>();
+    protected final Map<Type, MicroProfileTypedConverter> converters = new HashMap<>();
     protected final Map<Type, Converter> implicitConverters = new ConcurrentHashMap<>();
     private static final String ARRAY_SEPARATOR_REGEX = "(?<!\\\\)" + Pattern.quote(",");
 
-    public ConfigImpl() {
-        registerDefaultConverter();
-    }
-
-    private void registerDefaultConverter() {
-        converters.put(String.class, StringConverter.INSTANCE);
-        converters.put(Boolean.class, BooleanConverter.INSTANCE);
-        converters.put(boolean.class, BooleanConverter.INSTANCE);
-        converters.put(Double.class, DoubleConverter.INSTANCE);
-        converters.put(double.class, DoubleConverter.INSTANCE);
-        converters.put(Float.class, FloatConverter.INSTANCE);
-        converters.put(float.class, FloatConverter.INSTANCE);
-        converters.put(Integer.class, IntegerConverter.INSTANCE);
-        converters.put(int.class, IntegerConverter.INSTANCE);
-        converters.put(Long.class, LongConverter.INSTANCE);
-        converters.put(long.class, LongConverter.INSTANCE);
-
-        converters.put(Duration.class, DurationConverter.INSTANCE);
-        converters.put(LocalTime.class, LocalTimeConverter.INSTANCE);
-        converters.put(LocalDate.class, LocalDateConverter.INSTANCE);
-        converters.put(LocalDateTime.class, LocalDateTimeConverter.INSTANCE);
-        converters.put(OffsetTime.class, OffsetTimeConverter.INSTANCE);
-        converters.put(OffsetDateTime.class, OffsetDateTimeConverter.INSTANCE);
-        converters.put(Instant.class, InstantConverter.INSTANCE);
-
-        converters.put(URL.class, URLConverter.INSTANCE);
-        converters.put(Class.class, ClassConverter.INSTANCE);
-    }
-
-
     @Override
     public <T> Optional<T> getOptionalValue(String propertyName, Class<T> asType) {
         String value = getValue(propertyName);
@@ -179,7 +124,11 @@ public class ConfigImpl implements Confi
     }
 
     private <T> Converter getConverter(Class<T> asType) {
-        Converter converter = converters.get(asType);
+        MicroProfileTypedConverter microProfileTypedConverter = converters.get(asType);
+        Converter converter = null;
+        if(microProfileTypedConverter != null) {
+            converter = microProfileTypedConverter.getDelegate();
+        }
         if (converter == null) {
             converter = getImplicitConverter(asType);
         }
@@ -231,34 +180,7 @@ public class ConfigImpl implements Confi
         }
     }
 
-
-    public synchronized void addConverter(Converter<?> converter) {
-        if (converter == null) {
-            return;
-        }
-
-        Type targetType = getTypeOfConverter(converter.getClass());
-        if (targetType == null ) {
-            throw new IllegalStateException("Converter " + converter.getClass() + " must be a ParameterisedType");
-        }
-
-        Converter oldConverter = converters.get(targetType);
-        if (oldConverter == null || getPriority(converter) > getPriority(oldConverter)) {
-            converters.put(targetType, converter);
-        }
-    }
-
-    private int getPriority(Converter<?> converter) {
-        int priority = 100;
-        Priority priorityAnnotation = converter.getClass().getAnnotation(Priority.class);
-        if (priorityAnnotation != null) {
-            priority = priorityAnnotation.value();
-        }
-        return priority;
-    }
-
-
-    public Map<Type, Converter> getConverters() {
+    public Map<Type, MicroProfileTypedConverter> getConverters() {
         return converters;
     }
 
@@ -270,25 +192,7 @@ public class ConfigImpl implements Confi
 
     }
 
-    private Type getTypeOfConverter(Class clazz) {
-        if (clazz.equals(Object.class)) {
-            return null;
-        }
-
-        Type[] genericInterfaces = clazz.getGenericInterfaces();
-        for (Type genericInterface : genericInterfaces) {
-            if (genericInterface instanceof ParameterizedType) {
-                ParameterizedType pt = (ParameterizedType) genericInterface;
-                if (pt.getRawType().equals(Converter.class)) {
-                    Type[] typeArguments = pt.getActualTypeArguments();
-                    if (typeArguments.length != 1) {
-                        throw new IllegalStateException("Converter " + clazz + " must be a ParameterisedType");
-                    }
-                    return typeArguments[0];
-                }
-            }
-        }
-
-        return getTypeOfConverter(clazz.getSuperclass());
+    public void addConverter(Type type, MicroProfileTypedConverter<?> converter) {
+        converters.put(type, converter);
     }
 }
\ No newline at end of file

Modified: geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/ConfigValueImpl.java
URL: http://svn.apache.org/viewvc/geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/ConfigValueImpl.java?rev=1819198&r1=1819197&r2=1819198&view=diff
==============================================================================
--- geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/ConfigValueImpl.java (original)
+++ geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/ConfigValueImpl.java Sun Dec 24 03:52:02 2017
@@ -16,8 +16,9 @@
  */
 package org.apache.geronimo.config;
 
-import org.eclipse.microprofile.config.spi.Converter;
+import org.apache.geronimo.config.converters.MicroProfileTypedConverter;
 
+import javax.enterprise.inject.Typed;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.NoSuchElementException;
@@ -25,8 +26,6 @@ import java.util.Optional;
 import java.util.concurrent.TimeUnit;
 import java.util.logging.Logger;
 
-import javax.enterprise.inject.Typed;
-
 /**
  * @author <a href="mailto:struberg@apache.org">Mark Struberg</a>
  */
@@ -219,7 +218,7 @@ public class ConfigValueImpl<T> {
             return (T) value;
         }
 
-        Converter converter = config.getConverters().get(configEntryType);
+        MicroProfileTypedConverter converter = config.getConverters().get(configEntryType);
         if (converter == null) {
             throw new IllegalStateException("No Converter for type " + configEntryType);
         }

Modified: geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/DefaultConfigBuilder.java
URL: http://svn.apache.org/viewvc/geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/DefaultConfigBuilder.java?rev=1819198&r1=1819197&r2=1819198&view=diff
==============================================================================
--- geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/DefaultConfigBuilder.java (original)
+++ geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/DefaultConfigBuilder.java Sun Dec 24 03:52:02 2017
@@ -16,6 +16,22 @@
  */
 package org.apache.geronimo.config;
 
+import org.apache.geronimo.config.converters.BooleanConverter;
+import org.apache.geronimo.config.converters.ClassConverter;
+import org.apache.geronimo.config.converters.DoubleConverter;
+import org.apache.geronimo.config.converters.DurationConverter;
+import org.apache.geronimo.config.converters.FloatConverter;
+import org.apache.geronimo.config.converters.InstantConverter;
+import org.apache.geronimo.config.converters.IntegerConverter;
+import org.apache.geronimo.config.converters.LocalDateConverter;
+import org.apache.geronimo.config.converters.LocalDateTimeConverter;
+import org.apache.geronimo.config.converters.LocalTimeConverter;
+import org.apache.geronimo.config.converters.LongConverter;
+import org.apache.geronimo.config.converters.OffsetDateTimeConverter;
+import org.apache.geronimo.config.converters.OffsetTimeConverter;
+import org.apache.geronimo.config.converters.StringConverter;
+import org.apache.geronimo.config.converters.URLConverter;
+import org.apache.geronimo.config.converters.MicroProfileTypedConverter;
 import org.eclipse.microprofile.config.Config;
 import org.eclipse.microprofile.config.spi.ConfigBuilder;
 import org.eclipse.microprofile.config.spi.ConfigSource;
@@ -25,9 +41,21 @@ import org.apache.geronimo.config.config
 import org.apache.geronimo.config.configsource.SystemEnvConfigSource;
 import org.apache.geronimo.config.configsource.SystemPropertyConfigSource;
 
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.net.URL;
+import java.time.Duration;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.OffsetDateTime;
+import java.time.OffsetTime;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.ServiceLoader;
 
 import javax.enterprise.inject.Typed;
@@ -42,12 +70,16 @@ import static java.util.Arrays.asList;
 @Typed
 @Vetoed
 public class DefaultConfigBuilder implements ConfigBuilder {
-    protected ClassLoader forClassLoader;
+    private ClassLoader forClassLoader;
     private final List<ConfigSource> sources = new ArrayList<>();
-    private final List<Converter<?>> converters = new ArrayList<>();
     private boolean ignoreDefaultSources = true;
     private boolean ignoreDiscoveredSources = true;
     private boolean ignoreDiscoveredConverters = true;
+    private final Map<Type, MicroProfileTypedConverter<?>> wrappedConverters = new HashMap<>();
+
+    public DefaultConfigBuilder() {
+        this.registerDefaultConverters();
+    }
 
     @Override
     public ConfigBuilder addDefaultSources() {
@@ -75,12 +107,24 @@ public class DefaultConfigBuilder implem
 
     @Override
     public ConfigBuilder withConverters(Converter<?>... converters) {
-        this.converters.addAll(asList(converters));
+        for(Converter<?> converter : converters) {
+            Type typeOfConverter = getTypeOfConverter(converter.getClass());
+            registerConverter(typeOfConverter, new MicroProfileTypedConverter<>(converter));
+        }
         return this;
     }
 
     @Override
     public <T> ConfigBuilder withConverter(Class<T> type, int priority, Converter<T> converter) {
+        MicroProfileTypedConverter<T> microProfileTypedConverter = new MicroProfileTypedConverter<T>(converter, priority);
+        return registerConverter(type, microProfileTypedConverter);
+    }
+
+    private <T> ConfigBuilder registerConverter(Type type, MicroProfileTypedConverter<T> microProfileTypedConverter) {
+        MicroProfileTypedConverter<?> existing = wrappedConverters.get(type);
+        if(existing == null || microProfileTypedConverter.getPriority() > existing.getPriority()) {
+            wrappedConverters.put(type, microProfileTypedConverter);
+        }
         return this;
     }
 
@@ -119,14 +163,14 @@ public class DefaultConfigBuilder implem
 
         if (!ignoreDiscoveredConverters) {
             ServiceLoader<Converter> converterLoader = ServiceLoader.load(Converter.class, forClassLoader);
-            converterLoader.forEach(converters::add);
+            converterLoader.forEach(this::withConverters);
         }
 
         ConfigImpl config = new ConfigImpl();
         config.addConfigSources(configSources);
 
-        for (Converter<?> converter : converters) {
-            config.addConverter(converter);
+        for (Map.Entry<Type, MicroProfileTypedConverter<?>> entry : wrappedConverters.entrySet()) {
+            config.addConverter(entry.getKey(), entry.getValue());
         }
 
         return config;
@@ -141,4 +185,51 @@ public class DefaultConfigBuilder implem
 
         return configSources;
     }
+
+    private void registerDefaultConverters() {
+        wrappedConverters.put(String.class, new MicroProfileTypedConverter<>(StringConverter.INSTANCE));
+        wrappedConverters.put(Boolean.class, new MicroProfileTypedConverter<>(BooleanConverter.INSTANCE));
+        wrappedConverters.put(boolean.class, new MicroProfileTypedConverter<>(BooleanConverter.INSTANCE));
+        wrappedConverters.put(Double.class, new MicroProfileTypedConverter<>(DoubleConverter.INSTANCE));
+        wrappedConverters.put(double.class, new MicroProfileTypedConverter<>(DoubleConverter.INSTANCE));
+        wrappedConverters.put(Float.class, new MicroProfileTypedConverter<>(FloatConverter.INSTANCE));
+        wrappedConverters.put(float.class, new MicroProfileTypedConverter<>(FloatConverter.INSTANCE));
+        wrappedConverters.put(Integer.class, new MicroProfileTypedConverter<>(IntegerConverter.INSTANCE));
+        wrappedConverters.put(int.class, new MicroProfileTypedConverter<>(IntegerConverter.INSTANCE));
+        wrappedConverters.put(Long.class, new MicroProfileTypedConverter<>(LongConverter.INSTANCE));
+        wrappedConverters.put(long.class, new MicroProfileTypedConverter<>(LongConverter.INSTANCE));
+
+        wrappedConverters.put(Duration.class, new MicroProfileTypedConverter<>(DurationConverter.INSTANCE));
+        wrappedConverters.put(LocalTime.class, new MicroProfileTypedConverter<>(LocalTimeConverter.INSTANCE));
+        wrappedConverters.put(LocalDate.class, new MicroProfileTypedConverter<>(LocalDateConverter.INSTANCE));
+        wrappedConverters.put(LocalDateTime.class, new MicroProfileTypedConverter<>(LocalDateTimeConverter.INSTANCE));
+        wrappedConverters.put(OffsetTime.class, new MicroProfileTypedConverter<>(OffsetTimeConverter.INSTANCE));
+        wrappedConverters.put(OffsetDateTime.class, new MicroProfileTypedConverter<>(OffsetDateTimeConverter.INSTANCE));
+        wrappedConverters.put(Instant.class, new MicroProfileTypedConverter<>(InstantConverter.INSTANCE));
+
+        wrappedConverters.put(URL.class, new MicroProfileTypedConverter<>(URLConverter.INSTANCE));
+        wrappedConverters.put(Class.class, new MicroProfileTypedConverter<>(ClassConverter.INSTANCE));
+    }
+
+    private Type getTypeOfConverter(Class clazz) {
+        if (clazz.equals(Object.class)) {
+            return null;
+        }
+
+        Type[] genericInterfaces = clazz.getGenericInterfaces();
+        for (Type genericInterface : genericInterfaces) {
+            if (genericInterface instanceof ParameterizedType) {
+                ParameterizedType pt = (ParameterizedType) genericInterface;
+                if (pt.getRawType().equals(Converter.class)) {
+                    Type[] typeArguments = pt.getActualTypeArguments();
+                    if (typeArguments.length != 1) {
+                        throw new IllegalStateException("Converter " + clazz + " must be a ParameterisedType");
+                    }
+                    return typeArguments[0];
+                }
+            }
+        }
+
+        return getTypeOfConverter(clazz.getSuperclass());
+    }
 }

Added: geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/converters/MicroProfileTypedConverter.java
URL: http://svn.apache.org/viewvc/geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/converters/MicroProfileTypedConverter.java?rev=1819198&view=auto
==============================================================================
--- geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/converters/MicroProfileTypedConverter.java (added)
+++ geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/converters/MicroProfileTypedConverter.java Sun Dec 24 03:52:02 2017
@@ -0,0 +1,59 @@
+/*
+ *  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.geronimo.config.converters;
+
+import org.eclipse.microprofile.config.spi.Converter;
+
+import javax.annotation.Priority;
+
+public class MicroProfileTypedConverter<T> {
+    private final Converter<T> delegate;
+    private final int priority;
+
+    public MicroProfileTypedConverter(Converter<T> delegate) {
+        this(delegate, readPriority(delegate));
+    }
+
+    public MicroProfileTypedConverter(Converter<T> delegate, int priority) {
+        this.delegate = delegate;
+        this.priority = priority;
+    }
+
+    public Converter<T> getDelegate() {
+        return delegate;
+    }
+
+    public int getPriority() {
+        return priority;
+    }
+
+    private static <T> int readPriority(Converter<T> delegate) {
+        Priority priority = delegate.getClass().getAnnotation(Priority.class);
+        if(priority != null) {
+            return priority.value();
+        } else {
+            return 100;
+        }
+    }
+
+    public T convert(String value) {
+        return delegate.convert(value);
+    }
+}