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/30 05:53:54 UTC

svn commit: r1819570 - in /geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config: ./ converters/

Author: johndament
Date: Sat Dec 30 05:53:54 2017
New Revision: 1819570

URL: http://svn.apache.org/viewvc?rev=1819570&view=rev
Log:
GERONIMO-6597 Migrate array conversion to be implicit in behavior.

Fix some generic usage, clean up concurrency usage.

Added:
    geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/converters/ImplicitArrayConverter.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/DefaultConfigBuilder.java
    geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/converters/ImplicitConverter.java
    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
URL: http://svn.apache.org/viewvc/geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java?rev=1819570&r1=1819569&r2=1819570&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 Sat Dec 30 05:53:54 2017
@@ -16,29 +16,29 @@
  */
 package org.apache.geronimo.config;
 
-import org.apache.geronimo.config.converters.ImplicitConverter;
+import org.apache.geronimo.config.converters.ImplicitArrayConverter;
 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.Type;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Optional;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
+import static org.apache.geronimo.config.converters.ImplicitConverter.getImplicitConverter;
+
 /**
  * @author <a href="mailto:struberg@apache.org">Mark Struberg</a>
  * @author <a href="mailto:johndament@apache.org">John D. Ament</a>
@@ -49,9 +49,9 @@ public class ConfigImpl implements Confi
     protected Logger logger = Logger.getLogger(ConfigImpl.class.getName());
 
     protected final List<ConfigSource> configSources = new ArrayList<>();
-    protected final Map<Type, MicroProfileTypedConverter> converters = new HashMap<>();
-    protected final Map<Type, Converter> implicitConverters = new ConcurrentHashMap<>();
+    protected final ConcurrentMap<Type, MicroProfileTypedConverter> converters = new ConcurrentHashMap<>();
     private static final String ARRAY_SEPARATOR_REGEX = "(?<!\\\\)" + Pattern.quote(",");
+    private final ImplicitArrayConverter implicitArrayConverter = new ImplicitArrayConverter(this);
 
     @Override
     public <T> Optional<T> getOptionalValue(String propertyName, Class<T> asType) {
@@ -92,24 +92,13 @@ public class ConfigImpl implements Confi
 
     public <T> T convert(String value, Class<T> asType) {
         if (value != null) {
-            if(asType.isArray()) {
-                Class<?> elementType = asType.getComponentType();
-                List<?> elements = convertList(value, elementType);
-                Object arrayInst = Array.newInstance(elementType, elements.size());
-                for (int i = 0; i < elements.size(); i++) {
-                    Array.set(arrayInst, i, elements.get(i));
-                }
-                return (T) arrayInst;
-            } else {
-                Converter<T> converter = getConverter(asType);
-                return converter.convert(value);
-            }
+            return getConverter(asType).convert(value);
         }
         return null;
     }
 
     public <T> List<T> convertList(String rawValue, Class<T> arrayElementType) {
-        Converter<T> converter = getConverter(arrayElementType);
+        MicroProfileTypedConverter<T> converter = getConverter(arrayElementType);
         String[] parts = rawValue.split(ARRAY_SEPARATOR_REGEX);
         if(parts.length == 0) {
             return Collections.emptyList();
@@ -123,36 +112,21 @@ public class ConfigImpl implements Confi
         return elements;
     }
 
-    private <T> Converter getConverter(Class<T> asType) {
-        MicroProfileTypedConverter microProfileTypedConverter = converters.get(asType);
-        Converter converter = null;
-        if(microProfileTypedConverter != null) {
-            converter = microProfileTypedConverter.getDelegate();
-        }
-        if (converter == null) {
-            converter = getImplicitConverter(asType);
-        }
-        if (converter == null) {
+    private <T> MicroProfileTypedConverter<T> getConverter(Class<T> asType) {
+        MicroProfileTypedConverter<T> microProfileTypedConverter = converters.computeIfAbsent(asType, a -> handleMissingConverter(asType));
+        if (microProfileTypedConverter == null) {
             throw new IllegalArgumentException("No Converter registered for class " + asType);
         }
-        return converter;
+
+        return microProfileTypedConverter;
     }
 
-    private <T> Converter getImplicitConverter(Class<T> asType) {
-        Converter converter = implicitConverters.get(asType);
-        if (converter == null) {
-            synchronized (implicitConverters) {
-                converter = implicitConverters.get(asType);
-                if (converter == null) {
-                    // try to check whether the class is an 'implicit converter'
-                    converter = ImplicitConverter.getImplicitConverter(asType);
-                    if (converter != null) {
-                        implicitConverters.putIfAbsent(asType, converter);
-                    }
-                }
-            }
+    private <T> MicroProfileTypedConverter<T> handleMissingConverter(final Class<T> asType) {
+        if(asType.isArray()) {
+            return new MicroProfileTypedConverter<T>(value -> (T)implicitArrayConverter.convert(value, asType));
+        } else {
+            return getImplicitConverter(asType);
         }
-        return converter;
     }
 
     public ConfigValueImpl<String> access(String key) {
@@ -184,7 +158,6 @@ public class ConfigImpl implements Confi
         return converters;
     }
 
-
     private List<ConfigSource> sortDescending(List<ConfigSource> configSources) {
         configSources.sort(
                 (configSource1, configSource2) -> (configSource1.getOrdinal() > configSource2.getOrdinal()) ? -1 : 1);

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=1819570&r1=1819569&r2=1819570&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 Sat Dec 30 05:53:54 2017
@@ -75,7 +75,7 @@ public class DefaultConfigBuilder implem
     private boolean ignoreDefaultSources = true;
     private boolean ignoreDiscoveredSources = true;
     private boolean ignoreDiscoveredConverters = true;
-    private final Map<Type, MicroProfileTypedConverter<?>> wrappedConverters = new HashMap<>();
+    private final Map<Type, MicroProfileTypedConverter<?>> registeredConverters = new HashMap<>();
 
     public DefaultConfigBuilder() {
         this.registerDefaultConverters();
@@ -121,9 +121,9 @@ public class DefaultConfigBuilder implem
     }
 
     private <T> ConfigBuilder registerConverter(Type type, MicroProfileTypedConverter<T> microProfileTypedConverter) {
-        MicroProfileTypedConverter<?> existing = wrappedConverters.get(type);
+        MicroProfileTypedConverter<?> existing = registeredConverters.get(type);
         if(existing == null || microProfileTypedConverter.getPriority() > existing.getPriority()) {
-            wrappedConverters.put(type, microProfileTypedConverter);
+            registeredConverters.put(type, microProfileTypedConverter);
         }
         return this;
     }
@@ -169,7 +169,7 @@ public class DefaultConfigBuilder implem
         ConfigImpl config = new ConfigImpl();
         config.addConfigSources(configSources);
 
-        for (Map.Entry<Type, MicroProfileTypedConverter<?>> entry : wrappedConverters.entrySet()) {
+        for (Map.Entry<Type, MicroProfileTypedConverter<?>> entry : registeredConverters.entrySet()) {
             config.addConverter(entry.getKey(), entry.getValue());
         }
 
@@ -187,28 +187,28 @@ public class DefaultConfigBuilder implem
     }
 
     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));
+        registeredConverters.put(String.class, new MicroProfileTypedConverter<>(StringConverter.INSTANCE));
+        registeredConverters.put(Boolean.class, new MicroProfileTypedConverter<>(BooleanConverter.INSTANCE));
+        registeredConverters.put(boolean.class, new MicroProfileTypedConverter<>(BooleanConverter.INSTANCE));
+        registeredConverters.put(Double.class, new MicroProfileTypedConverter<>(DoubleConverter.INSTANCE));
+        registeredConverters.put(double.class, new MicroProfileTypedConverter<>(DoubleConverter.INSTANCE));
+        registeredConverters.put(Float.class, new MicroProfileTypedConverter<>(FloatConverter.INSTANCE));
+        registeredConverters.put(float.class, new MicroProfileTypedConverter<>(FloatConverter.INSTANCE));
+        registeredConverters.put(Integer.class, new MicroProfileTypedConverter<>(IntegerConverter.INSTANCE));
+        registeredConverters.put(int.class, new MicroProfileTypedConverter<>(IntegerConverter.INSTANCE));
+        registeredConverters.put(Long.class, new MicroProfileTypedConverter<>(LongConverter.INSTANCE));
+        registeredConverters.put(long.class, new MicroProfileTypedConverter<>(LongConverter.INSTANCE));
+
+        registeredConverters.put(Duration.class, new MicroProfileTypedConverter<>(DurationConverter.INSTANCE));
+        registeredConverters.put(LocalTime.class, new MicroProfileTypedConverter<>(LocalTimeConverter.INSTANCE));
+        registeredConverters.put(LocalDate.class, new MicroProfileTypedConverter<>(LocalDateConverter.INSTANCE));
+        registeredConverters.put(LocalDateTime.class, new MicroProfileTypedConverter<>(LocalDateTimeConverter.INSTANCE));
+        registeredConverters.put(OffsetTime.class, new MicroProfileTypedConverter<>(OffsetTimeConverter.INSTANCE));
+        registeredConverters.put(OffsetDateTime.class, new MicroProfileTypedConverter<>(OffsetDateTimeConverter.INSTANCE));
+        registeredConverters.put(Instant.class, new MicroProfileTypedConverter<>(InstantConverter.INSTANCE));
 
-        wrappedConverters.put(URL.class, new MicroProfileTypedConverter<>(URLConverter.INSTANCE));
-        wrappedConverters.put(Class.class, new MicroProfileTypedConverter<>(ClassConverter.INSTANCE));
+        registeredConverters.put(URL.class, new MicroProfileTypedConverter<>(URLConverter.INSTANCE));
+        registeredConverters.put(Class.class, new MicroProfileTypedConverter<>(ClassConverter.INSTANCE));
     }
 
     private Type getTypeOfConverter(Class clazz) {

Added: geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/converters/ImplicitArrayConverter.java
URL: http://svn.apache.org/viewvc/geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/converters/ImplicitArrayConverter.java?rev=1819570&view=auto
==============================================================================
--- geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/converters/ImplicitArrayConverter.java (added)
+++ geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/converters/ImplicitArrayConverter.java Sat Dec 30 05:53:54 2017
@@ -0,0 +1,42 @@
+/*
+ *  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.apache.geronimo.config.ConfigImpl;
+
+import java.lang.reflect.Array;
+import java.util.List;
+
+public class ImplicitArrayConverter {
+    private final ConfigImpl config;
+
+    public ImplicitArrayConverter(ConfigImpl config) {
+        this.config = config;
+    }
+    public Object convert(String value, Class<?> asType) {
+        Class<?> elementType = asType.getComponentType();
+        List<?> elements = config.convertList(value, elementType);
+        Object arrayInst = Array.newInstance(elementType, elements.size());
+        for (int i = 0; i < elements.size(); i++) {
+            Array.set(arrayInst, i, elements.get(i));
+        }
+        return arrayInst;
+    }
+}

Modified: geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/converters/ImplicitConverter.java
URL: http://svn.apache.org/viewvc/geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/converters/ImplicitConverter.java?rev=1819570&r1=1819569&r2=1819570&view=diff
==============================================================================
--- geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/converters/ImplicitConverter.java (original)
+++ geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/converters/ImplicitConverter.java Sat Dec 30 05:53:54 2017
@@ -29,10 +29,10 @@ import org.eclipse.microprofile.config.s
  */
 public abstract class ImplicitConverter {
 
-    public static Converter getImplicitConverter(Class<?> clazz) {
+    public static <T> MicroProfileTypedConverter<T> getImplicitConverter(Class<T> clazz) {
 
         // handle ct with String param
-        Converter converter = hasConverterCt(clazz, String.class);
+        Converter<T> converter = hasConverterCt(clazz, String.class);
         if (converter == null) {
             converter = hasConverterCt(clazz, CharSequence.class);
         }
@@ -48,24 +48,23 @@ public abstract class ImplicitConverter
         if (converter == null) {
             converter = hasConverterMethod(clazz, "parse", CharSequence.class);
         }
-
-        return converter;
+        if (converter == null) {
+            return null;
+        }
+        return new MicroProfileTypedConverter<T>(converter, 100);
     }
 
-    private static Converter hasConverterCt(Class<?> clazz, Class<?> paramType) {
+    private static <T> Converter<T> hasConverterCt(Class<T> clazz, Class<?> paramType) {
         try {
             final Constructor<?> declaredConstructor = clazz.getDeclaredConstructor(paramType);
             if (!declaredConstructor.isAccessible()) {
                 declaredConstructor.setAccessible(true);
             }
-            return new Converter() {
-                @Override
-                public Object convert(String value) {
-                    try {
-                        return declaredConstructor.newInstance(value);
-                    } catch (Exception e) {
-                        throw new RuntimeException(e);
-                    }
+            return value -> {
+                try {
+                    return (T)declaredConstructor.newInstance(value);
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
                 }
             };
         } catch (NoSuchMethodException e) {
@@ -74,7 +73,7 @@ public abstract class ImplicitConverter
         return null;
     }
 
-    private static Converter hasConverterMethod(Class<?> clazz, String methodName, Class<?> paramType) {
+    private static <T> Converter<T> hasConverterMethod(Class<T> clazz, String methodName, Class<?> paramType) {
         // handle valueOf with CharSequence param
         try {
             final Method method = clazz.getMethod(methodName, paramType);
@@ -82,14 +81,11 @@ public abstract class ImplicitConverter
                 method.setAccessible(true);
             }
             if (Modifier.isStatic(method.getModifiers())) {
-                return new Converter() {
-                    @Override
-                    public Object convert(String value) {
-                        try {
-                            return method.invoke(null, value);
-                        } catch (Exception e) {
-                            throw new RuntimeException(e);
-                        }
+                return value -> {
+                    try {
+                        return (T)method.invoke(null, value);
+                    } catch (Exception e) {
+                        throw new RuntimeException(e);
                     }
                 };
             }

Modified: 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=1819570&r1=1819569&r2=1819570&view=diff
==============================================================================
--- geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/converters/MicroProfileTypedConverter.java (original)
+++ geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/converters/MicroProfileTypedConverter.java Sat Dec 30 05:53:54 2017
@@ -36,10 +36,6 @@ public class MicroProfileTypedConverter<
         this.priority = priority;
     }
 
-    public Converter<T> getDelegate() {
-        return delegate;
-    }
-
     public int getPriority() {
         return priority;
     }