/*
 * Copyright 2005-2014 Red Hat, Inc.                                    
 *                                                                      
 * Red Hat 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 io.fabric8.cdi.producers;

import org.apache.deltaspike.core.api.config.ConfigProperty;
import org.apache.deltaspike.core.api.config.ConfigResolver;

import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.enterprise.inject.spi.Producer;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.Set;

public class ConfigurationProducer<T> implements Producer<T> {

    private final String configurationId;
    private final Class<T> type;

    public ConfigurationProducer(String configurationId, Class<T> type) {
        this.type = type;
        this.configurationId = configurationId;
    }

    @Override
    public T produce(CreationalContext<T> ctx) {
        if (configurationId == null) {
            throw new IllegalArgumentException("No service id has been specified.");
        }
        try {
            T bean = (T) type.newInstance();
            for (Field f : type.getDeclaredFields()) {
                ConfigProperty configProperty = f.getAnnotation(ConfigProperty.class);
                String name = configProperty.name();
                String defaultValue = configProperty.defaultValue();

                String value = ConfigResolver.getPropertyValue((configurationId + "_" + name)
                        .replaceAll("-", "_")
                        .toUpperCase(), defaultValue);
                if (f.getType().isAssignableFrom(String.class)) {
                    f.setAccessible(true);
                    f.set(bean, value);
                } else if (f.getType().isAssignableFrom(Boolean.class)) {
                    f.setAccessible(true);
                    f.set(bean, Boolean.parseBoolean(value));
                } else if (f.getType().isAssignableFrom(Short.class)) {
                    f.setAccessible(true);
                    f.set(bean, Short.parseShort(value));
                } else if (f.getType().isAssignableFrom(Integer.class)) {
                    f.setAccessible(true);
                    f.set(bean, Integer.parseInt(value));
                } else if (f.getType().isAssignableFrom(Long.class)) {
                    f.setAccessible(true);
                    f.set(bean, Long.parseLong(value));
                } else if (f.getType().isAssignableFrom(Double.class)) {
                    f.setAccessible(true);
                    f.set(bean, Double.parseDouble(value));
                } else if (f.getType().isAssignableFrom(Float.class)) {
                    f.setAccessible(true);
                    f.set(bean, Float.parseFloat(value));
                }
            }
            return bean;
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void dispose(T instance) {
        //do nothing
    }

    @Override
    public Set<InjectionPoint> getInjectionPoints() {
        return Collections.emptySet();
    }

    private static String toEnv(String str) {
        return str.toUpperCase().replaceAll("-", "_");
    }
}

@@ -2014,16 +2014,66 @@
 class);%0A
+                if (configProperty != null) %7B%0A    
         
@@ -2113,24 +2113,28 @@
 rty.name();%0A
+    
             
@@ -2203,24 +2203,28 @@
             
+    
 String value
@@ -2313,16 +2313,20 @@
         
+    
 .replace
@@ -2363,16 +2363,20 @@
         
+   
+ 
 .toUpper
@@ -2394,24 +2394,28 @@
 aultValue);%0A
+    
             
@@ -2480,32 +2480,36 @@
                 
+    
 f.setAccessible(
@@ -2527,32 +2527,36 @@
                 
+  
+  
 f.set(bean, valu
@@ -2555,24 +2555,28 @@
 an, value);%0A
+    
             
@@ -2629,32 +2629,36 @@
 olean.class)) %7B%0A
+    
                 
@@ -2696,32 +2696,36 @@
                 
+    
 f.set(bean, Bool
@@ -2742,32 +2742,36 @@
 oolean(value));%0A
+    
                 
@@ -2838,32 +2838,36 @@
                 
+   
+ 
 f.setAccessible(
@@ -2865,32 +2865,36 @@
 cessible(true);%0A
+    
                 
@@ -2943,32 +2943,36 @@
                 
+ 
+   
 %7D else if (f.get
@@ -3025,32 +3025,36 @@
                 
+  
+  
 f.setAccessible(
@@ -3052,32 +3052,36 @@
 cessible(true);%0A
+    
                 
@@ -3130,32 +3130,36 @@
                 
+    
 %7D else if (f.get
@@ -3209,32 +3209,36 @@
                 
+ 
+   
 f.setAccessible(
@@ -3236,32 +3236,36 @@
 cessible(true);%0A
+    
                 
@@ -3312,32 +3312,36 @@
                 
+   
+ 
 %7D else if (f.get
@@ -3393,32 +3393,36 @@
                 
+    
 f.setAccessible(
@@ -3440,32 +3440,36 @@
                 
+ 
+   
 f.set(bean, Doub
@@ -3500,32 +3500,36 @@
                 
+  
+  
 %7D else if (f.get
@@ -3560,32 +3560,36 @@
 Float.class)) %7B%0A
+    
                 
@@ -3627,32 +3627,36 @@
                 
+    
 f.set(bean, Floa
@@ -3669,32 +3669,54 @@
 eFloat(value));%0A
+                    %7D%0A
                 

Fix potential NPE in ConfigurationProducer.