GERONIMO-6579 - Adding support for injecting Suppliers.

git-svn-id: https://svn.apache.org/repos/asf/geronimo/components/config/trunk@1806652 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigInjectionBean.java b/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigInjectionBean.java
index dde1eca..e438c0c 100644
--- a/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigInjectionBean.java
+++ b/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigInjectionBean.java
@@ -16,13 +16,10 @@
  */
 package org.apache.geronimo.config.cdi;
 
-import java.lang.annotation.Annotation;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Optional;
-import java.util.Set;
+import org.apache.geronimo.config.ConfigImpl;
+import org.eclipse.microprofile.config.Config;
+import org.eclipse.microprofile.config.ConfigProvider;
+import org.eclipse.microprofile.config.inject.ConfigProperty;
 
 import javax.enterprise.context.Dependent;
 import javax.enterprise.context.spi.CreationalContext;
@@ -35,11 +32,14 @@
 import javax.enterprise.inject.spi.PassivationCapable;
 import javax.enterprise.util.AnnotationLiteral;
 import javax.inject.Provider;
-
-import org.apache.geronimo.config.ConfigImpl;
-import org.eclipse.microprofile.config.Config;
-import org.eclipse.microprofile.config.ConfigProvider;
-import org.eclipse.microprofile.config.inject.ConfigProperty;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Supplier;
 
 /**
  * @author <a href="mailto:struberg@yahoo.de">Mark Struberg</a>
@@ -123,6 +123,11 @@
                 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());
+            }
         }
         else {
             Class clazz = (Class) annotated.getBaseType();
diff --git a/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigSupplier.java b/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigSupplier.java
new file mode 100644
index 0000000..47eb3ee
--- /dev/null
+++ b/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigSupplier.java
@@ -0,0 +1,48 @@
+/*
+ *  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.cdi;
+
+import org.apache.geronimo.config.ConfigImpl;
+import org.eclipse.microprofile.config.inject.ConfigProperty;
+
+import java.util.function.Supplier;
+
+class ConfigSupplier<T> implements Supplier<T> {
+
+    private final Class<T> clazz;
+    private final String key;
+    private final String defaultValue;
+    private final ConfigImpl config;
+
+    ConfigSupplier(Class<T> clazz, String key, String defaultValue, ConfigImpl config) {
+        this.clazz = clazz;
+        this.key = key;
+        this.defaultValue = defaultValue;
+        this.config = config;
+    }
+
+    @Override
+    public T get() {
+        String rawValue = config.getOptionalValue(key, String.class).orElse(defaultValue);
+        if (ConfigProperty.UNCONFIGURED_VALUE.equals(rawValue)) { // property not set
+            return null;
+        }
+        return config.convert(rawValue, clazz);
+    }
+}
diff --git a/impl/src/test/java/org/apache/geronimo/config/test/internal/SupplierTest.java b/impl/src/test/java/org/apache/geronimo/config/test/internal/SupplierTest.java
new file mode 100644
index 0000000..500220e
--- /dev/null
+++ b/impl/src/test/java/org/apache/geronimo/config/test/internal/SupplierTest.java
@@ -0,0 +1,112 @@
+/*
+ *  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.function.Supplier;
+
+public class SupplierTest extends Arquillian{
+    private static final String SOME_KEY = "org.apache.geronimo.config.test.internal.somekey";
+    private static final String SUPPLIER_DEFAULT_VALUE = "supplierDefaultValue";
+    private static final String SOME_INT_KEY = "some.supplier.int.key";
+
+    @Deployment
+    public static WebArchive deploy() {
+        System.setProperty(SOME_KEY, "someval");
+        JavaArchive testJar = ShrinkWrap
+                .create(JavaArchive.class, "configSupplierTest.jar")
+                .addClasses(SupplierTest.class, SomeBean.class)
+                .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")
+                .as(JavaArchive.class);
+
+        return ShrinkWrap
+                .create(WebArchive.class, "supplierTest.war")
+                .addAsLibrary(testJar);
+    }
+
+    private @Inject SomeBean someBean;
+
+
+    @Test
+    public void testConfigProvider() {
+        String someval = "someval";
+        System.setProperty(SOME_KEY, someval);
+        String myconfig = someBean.getMyconfig();
+        Assert.assertEquals(myconfig, someval);
+
+        String otherval = "otherval";
+        System.setProperty(SOME_KEY, otherval);
+        myconfig = someBean.getMyconfig();
+        Assert.assertEquals(myconfig, otherval);
+
+        Assert.assertEquals(someBean.getAnotherconfig().get(), SUPPLIER_DEFAULT_VALUE);
+
+        System.setProperty(SOME_INT_KEY, "42");
+        Assert.assertEquals(someBean.getSomeInt(), 42);
+
+        Assert.assertNull(someBean.getUndefinedValue().get());
+    }
+
+    @RequestScoped
+    public static class SomeBean {
+
+        @Inject
+        @ConfigProperty(name=SOME_KEY)
+        private Supplier<String> myconfig;
+
+        @Inject
+        @ConfigProperty(name = SOME_INT_KEY)
+        private Supplier<Integer> someIntValue;
+
+        @Inject
+        @ConfigProperty(name="missing.key",defaultValue = SUPPLIER_DEFAULT_VALUE)
+        private Supplier<String> anotherconfig;
+
+        @Inject
+        @ConfigProperty(name = "UNDEFINED_VALUE")
+        private Supplier<Integer> undefinedValue;
+
+        public int getSomeInt() {
+            return someIntValue.get();
+        }
+
+        public String getMyconfig() {
+            return myconfig.get();
+        }
+
+        public Supplier<String> getAnotherconfig() {
+            return anotherconfig;
+        }
+
+        public Supplier<Integer> getUndefinedValue() {
+            return undefinedValue;
+        }
+    }
+}