geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From johndam...@apache.org
Subject svn commit: r1819195 - in /geronimo/components/config/trunk/impl/src: main/java/org/apache/geronimo/config/ main/java/org/apache/geronimo/config/cdi/ main/java/org/apache/geronimo/config/converters/ test/java/org/apache/geronimo/config/test/internal/
Date Sun, 24 Dec 2017 01:56:34 GMT
Author: johndament
Date: Sun Dec 24 01:56:34 2017
New Revision: 1819195

URL: http://svn.apache.org/viewvc?rev=1819195&view=rev
Log:
GERONIMO-6597 Implementing array, list, set conversion logic.  Support for class as a built
in converter.

Added:
    geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/converters/ClassConverter.java
    geronimo/components/config/trunk/impl/src/test/java/org/apache/geronimo/config/test/internal/ArrayTypeTest.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/cdi/ConfigInjectionBean.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=1819195&r1=1819194&r2=1819195&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 01:56:34 2017
@@ -16,6 +16,7 @@
  */
 package org.apache.geronimo.config;
 
+import java.lang.reflect.Array;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import java.net.URL;
@@ -36,9 +37,11 @@ import java.util.Optional;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.logging.Level;
 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;
@@ -70,10 +73,10 @@ import javax.enterprise.inject.Vetoed;
 public class ConfigImpl implements Config {
     protected Logger logger = Logger.getLogger(ConfigImpl.class.getName());
 
-    protected List<ConfigSource> configSources = new ArrayList<>();
-    protected Map<Type, Converter> converters = new HashMap<>();
-    protected Map<Type, Converter> implicitConverters = new ConcurrentHashMap<>();
-
+    protected final List<ConfigSource> configSources = new ArrayList<>();
+    protected final Map<Type, Converter> converters = new HashMap<>();
+    protected final Map<Type, Converter> implicitConverters = new ConcurrentHashMap<>();
+    private static final String ARRAY_SEPARATOR_REGEX = "(?<!\\\\)" + Pattern.quote(",");
 
     public ConfigImpl() {
         registerDefaultConverter();
@@ -101,6 +104,7 @@ public class ConfigImpl implements Confi
         converters.put(Instant.class, InstantConverter.INSTANCE);
 
         converters.put(URL.class, URLConverter.INSTANCE);
+        converters.put(Class.class, ClassConverter.INSTANCE);
     }
 
 
@@ -143,13 +147,37 @@ public class ConfigImpl implements Confi
 
     public <T> T convert(String value, Class<T> asType) {
         if (value != null) {
-            Converter<T> converter = getConverter(asType);
-            return converter.convert(value);
+            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 null;
     }
 
+    public <T> List<T> convertList(String rawValue, Class<T> arrayElementType)
{
+        Converter<T> converter = getConverter(arrayElementType);
+        String[] parts = rawValue.split(ARRAY_SEPARATOR_REGEX);
+        if(parts.length == 0) {
+            return Collections.emptyList();
+        }
+        List<T> elements = new ArrayList<>(parts.length);
+        for (String part : parts) {
+            part = part.replace("\\,", ",");
+            T converted = converter.convert(part);
+            elements.add(converted);
+        }
+        return elements;
+    }
+
     private <T> Converter getConverter(Class<T> asType) {
         Converter converter = converters.get(asType);
         if (converter == null) {
@@ -197,7 +225,10 @@ public class ConfigImpl implements Confi
         allConfigSources.addAll(configSourcesToAdd);
 
         // finally put all the configSources back into the map
-        configSources = sortDescending(allConfigSources);
+        synchronized (configSources) {
+            configSources.clear();
+            configSources.addAll(sortDescending(allConfigSources));
+        }
     }
 
 

Modified: geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigInjectionBean.java
URL: http://svn.apache.org/viewvc/geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigInjectionBean.java?rev=1819195&r1=1819194&r2=1819195&view=diff
==============================================================================
--- geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigInjectionBean.java
(original)
+++ geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigInjectionBean.java
Sun Dec 24 01:56:34 2017
@@ -37,6 +37,8 @@ import java.lang.reflect.ParameterizedTy
 import java.lang.reflect.Type;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
 import java.util.Optional;
 import java.util.Set;
 import java.util.function.Supplier;
@@ -111,22 +113,42 @@ public class ConfigInjectionBean<T> impl
         if (annotated.getBaseType() instanceof ParameterizedType) {
             ParameterizedType paramType = (ParameterizedType) annotated.getBaseType();
             Type rawType = paramType.getRawType();
-
-            // handle Provider<T>
-            if (rawType instanceof Class && ((Class) rawType).isAssignableFrom(Provider.class)
&& paramType.getActualTypeArguments().length == 1) {
-                Class clazz = (Class) paramType.getActualTypeArguments()[0]; //X TODO check
type again, etc
-                return getConfigValue(key, defaultValue, clazz);
-            }
-
-            // handle Optional<T>
-            if (rawType instanceof Class && ((Class) rawType).isAssignableFrom(Optional.class)
&& paramType.getActualTypeArguments().length == 1) {
-                Class clazz = (Class) paramType.getActualTypeArguments()[0]; //X TODO check
type again, etc
-                return (T) getConfig().getOptionalValue(key, clazz);
-            }
-
-            if (rawType instanceof Class && ((Class) rawType).isAssignableFrom(Supplier.class)
&& paramType.getActualTypeArguments().length == 1) {
-                Class clazz = (Class) paramType.getActualTypeArguments()[0]; //X TODO check
type again, etc
-                return (T) new ConfigSupplier(clazz, key, defaultValue, (ConfigImpl)getConfig());
+            if(rawType instanceof Class && paramType.getActualTypeArguments().length
== 1) {
+                // handle Provider<T>
+                Class<?> rawTypeClass = ((Class<?>) rawType);
+                if (rawTypeClass.isAssignableFrom(Provider.class)) {
+                    Class clazz = (Class) paramType.getActualTypeArguments()[0]; //X TODO
check type again, etc
+                    return getConfigValue(key, defaultValue, clazz);
+                }
+
+                // handle Optional<T>
+                if (rawTypeClass.isAssignableFrom(Optional.class)) {
+                    Class clazz = (Class) paramType.getActualTypeArguments()[0]; //X TODO
check type again, etc
+                    return (T) getConfig().getOptionalValue(key, clazz);
+                }
+
+                if (rawTypeClass.isAssignableFrom(Supplier.class)) {
+                    Class clazz = (Class) paramType.getActualTypeArguments()[0]; //X TODO
check type again, etc
+                    return (T) new ConfigSupplier(clazz, key, defaultValue, (ConfigImpl)getConfig());
+                }
+
+                if (rawTypeClass.isAssignableFrom(Set.class)) {
+                    Class clazz = (Class) paramType.getActualTypeArguments()[0]; //X TODO
check type again, etc
+
+                    // read the array type, convert it to a Set
+                    ConfigImpl config = (ConfigImpl) getConfig();
+                    String value = config.getValue(key);
+                    List<Object> elements = config.convertList(value, clazz);
+                    return (T)new LinkedHashSet<>(elements);
+                }
+
+                if (rawTypeClass.isAssignableFrom(List.class)) {
+                    Class clazz = (Class) paramType.getActualTypeArguments()[0]; //X TODO
check type again, etc
+                    // read the array type, convert it to a List
+                    ConfigImpl config = (ConfigImpl) getConfig();
+                    String value = config.getValue(key);
+                    return (T)config.convertList(value, clazz);
+                }
             }
         }
         else {

Added: geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/converters/ClassConverter.java
URL: http://svn.apache.org/viewvc/geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/converters/ClassConverter.java?rev=1819195&view=auto
==============================================================================
--- geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/converters/ClassConverter.java
(added)
+++ geronimo/components/config/trunk/impl/src/main/java/org/apache/geronimo/config/converters/ClassConverter.java
Sun Dec 24 01:56:34 2017
@@ -0,0 +1,41 @@
+/*
+ *  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;
+import javax.enterprise.inject.Vetoed;
+
+@Priority(1)
+@Vetoed
+public class ClassConverter implements Converter<Class>{
+    public static final Converter<Class> INSTANCE = new ClassConverter();
+    @Override
+    public Class convert(String value) {
+        if(value == null) {
+            return null;
+        }
+        try {
+            return Class.forName(value);
+        } catch (ClassNotFoundException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+}

Added: geronimo/components/config/trunk/impl/src/test/java/org/apache/geronimo/config/test/internal/ArrayTypeTest.java
URL: http://svn.apache.org/viewvc/geronimo/components/config/trunk/impl/src/test/java/org/apache/geronimo/config/test/internal/ArrayTypeTest.java?rev=1819195&view=auto
==============================================================================
--- geronimo/components/config/trunk/impl/src/test/java/org/apache/geronimo/config/test/internal/ArrayTypeTest.java
(added)
+++ geronimo/components/config/trunk/impl/src/test/java/org/apache/geronimo/config/test/internal/ArrayTypeTest.java
Sun Dec 24 01:56:34 2017
@@ -0,0 +1,118 @@
+/*
+ *  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.test.internal;
+
+import org.eclipse.microprofile.config.inject.ConfigProperty;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.testng.Arquillian;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
+
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import static java.util.Arrays.asList;
+
+public class ArrayTypeTest extends Arquillian {
+    private static final String SOME_KEY = "org.apache.geronimo.config.test.internal.somekey";
+    private static final String SOME_OTHER_KEY = "org.apache.geronimo.config.test.internal.someotherkey";
+
+    @Deployment
+    public static WebArchive deploy() {
+        System.setProperty(SOME_KEY, "1,2,3");
+        System.setProperty(SOME_OTHER_KEY, "1,2\\,3");
+        JavaArchive testJar = ShrinkWrap
+                .create(JavaArchive.class, "arrayTest.jar")
+                .addClasses(ArrayTypeTest.class, SomeBean.class)
+                .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
+
+        return ShrinkWrap
+                .create(WebArchive.class, "arrayTest.war")
+                .addAsLibrary(testJar);
+    }
+
+    @Inject
+    private SomeBean someBean;
+
+    @Test
+    public void testArraySetListInjection() {
+        Assert.assertEquals(someBean.getStringValue(), "1,2,3");
+        Assert.assertEquals(someBean.getMyconfig(), new int[]{1,2,3});
+        Assert.assertEquals(someBean.getIntValues(), asList(1,2,3));
+        Assert.assertEquals(someBean.getIntSet(), new LinkedHashSet<>(asList(1,2,3)));
+    }
+
+    @Test
+    public void testListWithEscaping() {
+        Assert.assertEquals(someBean.getValues(), asList("1","2,3"));
+    }
+
+    @RequestScoped
+    public static class SomeBean {
+
+        @Inject
+        @ConfigProperty(name=SOME_KEY)
+        private int[] myconfig;
+
+        @Inject
+        @ConfigProperty(name=SOME_KEY)
+        private List<Integer> intValues;
+
+        @Inject
+        @ConfigProperty(name=SOME_KEY)
+        private Set<Integer> intSet;
+
+        @Inject
+        @ConfigProperty(name=SOME_KEY)
+        private String stringValue;
+
+        @Inject
+        @ConfigProperty(name=SOME_OTHER_KEY)
+        private List<String> values;
+
+        public String getStringValue() {
+            return stringValue;
+        }
+
+        public int[] getMyconfig() {
+            return myconfig;
+        }
+
+        public List<Integer> getIntValues() {
+            return intValues;
+        }
+
+        public Set<Integer> getIntSet() {
+            return intSet;
+        }
+
+        public List<String> getValues() {
+            return values;
+        }
+    }
+}



Mime
View raw message