Package com.netflix.paas.config.base

Source Code of com.netflix.paas.config.base.ConfigurationProxyUtils$PropertyWrapperSupplier

/*******************************************************************************
* /***
*  *
*  *  Copyright 2013 Netflix, Inc.
*  *
*  *     Licensed 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 com.netflix.paas.config.base;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.Maps;
import com.netflix.config.DynamicPropertyFactory;
import com.netflix.config.PropertyWrapper;
import com.netflix.governator.annotations.Configuration;
import com.netflix.paas.config.annotations.DefaultValue;
import com.netflix.paas.config.annotations.Dynamic;

import java.lang.reflect.Field;

import org.apache.commons.configuration.AbstractConfiguration;

/**
* Utility class used by ConfigurationProxyFactory implementations to proxy methods of a
* configuration interface using information from the Configuration annotation
*
* @author elandau
*/
public class ConfigurationProxyUtils  {
    public static class PropertyWrapperSupplier<T> implements Supplier<T> {
        private final PropertyWrapper<T> wrapper;
        public PropertyWrapperSupplier(PropertyWrapper<T> wrapper) {
            this.wrapper = wrapper;
        }
       
        @Override
        public T get() {
            return this.wrapper.getValue();
        }
    }
   
    static Supplier<?> getDynamicSupplier(Class<?> type, String key, String defaultValue, DynamicPropertyFactory propertyFactory) {
        if (type.isAssignableFrom(String.class)) {
            return new PropertyWrapperSupplier<String>(
                    propertyFactory.getStringProperty(
                            key,
                            defaultValue));
        }
        else if (type.isAssignableFrom(Integer.class)) {
            return new PropertyWrapperSupplier<Integer>(
                    propertyFactory.getIntProperty(
                            key,
                            defaultValue == null ? 0 : Integer.parseInt(defaultValue)));
        }
        else if (type.isAssignableFrom(Double.class)) {
            return new PropertyWrapperSupplier<Double>(
                    propertyFactory.getDoubleProperty(
                            key,
                            defaultValue == null ? 0.0 : Double.parseDouble(defaultValue)));
        }
        else if (type.isAssignableFrom(Long.class)) {
            return new PropertyWrapperSupplier<Long>(
                    propertyFactory.getLongProperty(
                            key,
                            defaultValue == null ? 0L : Long.parseLong(defaultValue)));
        }
        else if (type.isAssignableFrom(Boolean.class)) {
            return new PropertyWrapperSupplier<Boolean>(
                    propertyFactory.getBooleanProperty(
                            key,
                            defaultValue == null ? false : Boolean.parseBoolean(defaultValue)));
        }
        throw new RuntimeException("Unsupported value type " + type.getCanonicalName());
    }
   
    static Supplier<?> getStaticSupplier(Class<?> type, String key, String defaultValue, AbstractConfiguration configuration) {
        if (type.isAssignableFrom(String.class)) {
            return Suppliers.ofInstance(
                    configuration.getString(
                            key,
                            defaultValue));
        }
        else if (type.isAssignableFrom(Integer.class)) {
            return Suppliers.ofInstance(
                    configuration.getInteger(
                            key,
                            defaultValue == null ? 0 : Integer.parseInt(defaultValue)));
        }
        else if (type.isAssignableFrom(Double.class)) {
            return Suppliers.ofInstance(
                    configuration.getDouble(
                            key,
                            defaultValue == null ? 0.0 : Double.parseDouble(defaultValue)));
        }
        else if (type.isAssignableFrom(Long.class)) {
            return Suppliers.ofInstance(
                    configuration.getLong(
                            key,
                            defaultValue == null ? 0L : Long.parseLong(defaultValue)));
        }
        else if (type.isAssignableFrom(Boolean.class)) {
            return Suppliers.ofInstance(
                    configuration.getBoolean(
                            key,
                            defaultValue == null ? false : Boolean.parseBoolean(defaultValue)));
        }
        throw new RuntimeException("Unsupported value type " + type.getCanonicalName());
    }
   
    static String getPropertyName(Method method, Configuration c) {
        String name = c.value();
        if (name.isEmpty()) {
            name = method.getName();
            name = StringUtils.removeStart(name, "is");
            name = StringUtils.removeStart(name, "get");
            name = name.toLowerCase();
        }
        return name;
    }
   
    static String getPropertyName(Field field, Configuration c) {
        String name = c.value();
        if (name.isEmpty()) {
            return field.getName();
        }
        return name;
    }
   
    static <T> Map<String, Supplier<?>> getMethodSuppliers(Class<T> configClass, DynamicPropertyFactory propertyFactory, AbstractConfiguration configuration) {
        final Map<String, Supplier<?>> properties = Maps.newHashMap();
       
        for (Method method : configClass.getMethods()) {
            Configuration c = method.getAnnotation(Configuration.class);
            if (c == null)
                continue;
            String defaultValue = null;
            DefaultValue dv = method.getAnnotation(DefaultValue.class);
            if (dv != null)
                defaultValue = dv.value();
           
            String name = getPropertyName(method, c);
           
            if (method.getReturnType().isAssignableFrom(Supplier.class)) {
                Type returnType = method.getGenericReturnType();
   
                if(returnType instanceof ParameterizedType){
                    ParameterizedType type = (ParameterizedType) returnType;
                    Class<?> actualType = (Class<?>)type.getActualTypeArguments()[0];
                   
                    properties.put(method.getName(),
                            method.getAnnotation(Dynamic.class) != null
                            ? Suppliers.ofInstance(getDynamicSupplier(actualType, name, defaultValue, propertyFactory))
                            : Suppliers.ofInstance(getStaticSupplier(actualType, name, defaultValue, configuration)));
                }
                else {
                    throw new RuntimeException("We'll get to this later");
                }
            }
            else {
                properties.put(method.getName(),
                        method.getAnnotation(Dynamic.class) != null
                        ? getDynamicSupplier(method.getReturnType(), name, defaultValue, propertyFactory)
                        : getStaticSupplier (method.getReturnType(), name, defaultValue, configuration));
            }
        }
       
        return properties;
    }
   
    static void assignFieldValues(final Object obj, Class<?> type, DynamicPropertyFactory propertyFactory, AbstractConfiguration configuration) throws Exception {
       
        // Iterate through all fields and set initial value as well as set up dynamic properties
        // where necessary
        for (final Field field : type.getFields()) {
            Configuration c = field.getAnnotation(Configuration.class);
            if (c == null)
                continue;
           
            String defaultValue = field.get(obj).toString();
            String name         = ConfigurationProxyUtils.getPropertyName(field, c);
            Supplier<?> supplier = ConfigurationProxyUtils.getStaticSupplier(field.getType(), name, defaultValue, configuration);
            field.set(obj,  supplier.get());
           
            if (field.getAnnotation(Dynamic.class) != null) {
                final PropertyWrapper<?> property;
                if (field.getType().isAssignableFrom(String.class)) {
                    property = propertyFactory.getStringProperty(
                                    name,
                                    defaultValue);
                }
                else if (field.getType().isAssignableFrom(Integer.class)) {
                    property = propertyFactory.getIntProperty(
                                    name,
                                    defaultValue == null ? 0 : Integer.parseInt(defaultValue));
                }
                else if (field.getType().isAssignableFrom(Double.class)) {
                    property = propertyFactory.getDoubleProperty(
                                    name,
                                    defaultValue == null ? 0.0 : Double.parseDouble(defaultValue));
                }
                else if (field.getType().isAssignableFrom(Long.class)) {
                    property = propertyFactory.getLongProperty(
                                    name,
                                    defaultValue == null ? 0L : Long.parseLong(defaultValue));
                }
                else if (field.getType().isAssignableFrom(Boolean.class)) {
                    property = propertyFactory.getBooleanProperty(
                                    name,
                                    defaultValue == null ? false : Boolean.parseBoolean(defaultValue));
                }
                else {
                    throw new RuntimeException("Unsupported type " + field.getType());
                }
               
                property.addCallback(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            field.set(obj, property.getValue());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        }       
    }

}
TOP

Related Classes of com.netflix.paas.config.base.ConfigurationProxyUtils$PropertyWrapperSupplier

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.