All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jetbrick.config.AbstractConfig Maven / Gradle / Ivy

There is a newer version: 2.2.0
Show newest version
/**
 * Copyright 2013-2016 Guoqiang Chen, Shanghai, China. All rights reserved.
 *
 *   Author: Guoqiang Chen
 *    Email: [email protected]
 *   WebURL: https://github.com/subchen
 *
 * 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 jetbrick.config;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import jetbrick.bean.KlassInfo;
import jetbrick.bean.PropertyInfo;
import jetbrick.typecast.TypeCastUtils;
import jetbrick.util.ClassLoaderUtils;
import jetbrick.util.ClassUtils;
import jetbrick.util.IdentifiedNameUtils;
import jetbrick.util.StringUtils;

/**
 * properties 配置文件抽象处理类.
 *
 * @author Guoqiang Chen
 */
public abstract class AbstractConfig {
    protected final Map config;

    public AbstractConfig(Map map) {
        config = new HashMap(map);
    }

    public AbstractConfig(Properties props) {
        config = new HashMap(props.size());
        for (String key : props.stringPropertyNames()) {
            String value = props.getProperty(key);
            config.put(key, value);
        }
    }

    // -----------------------------------------------------------------
    public boolean isEmpty() {
        return config.isEmpty();
    }

    public int size() {
        return config.size();
    }

    public Set keySet() {
        return config.keySet();
    }

    public Set keySet(String prefix) {
        Set keys = new LinkedHashSet();
        for (String key : config.keySet()) {
            if (key.startsWith(prefix)) {
                keys.add(key);
            }
        }
        return keys.isEmpty() ? Collections. emptySet() : keys;
    }

    public Map asMap() {
        return Collections.unmodifiableMap(config);
    }

    // -----------------------------------------------------------------

    /**
     * 获取属性值.
     *
     * @param name              键值
     * @param targetClass       目标类(不允许为空),
     *                          如果 targetClass 为 Object.class,那么自动将 classname 转换为 instance.
     *                          如果 value 是 "$" 开头的引用,则返回引用对象 instance
     * @param defaultValue      默认值
     * @return                  属性值对象
     */
    protected  T doGetValue(String name, Class targetClass, String defaultValue) {
        String value = config.get(name);
        return stringAsObject(value, targetClass, defaultValue);
    }

    /**
     * 获取属性值,将逗号分隔的属性值转换为 List 对象.
     *
     * @param name              键值
     * @param elementType       目标类(不允许为空),
     *                          如果 elementType 为 Object.class,那么自动将 classname 转换为 instance.
     *                          如果 value 是 "$" 开头的引用,则返回引用对象 instance
     * @param defaultValues     默认值
     * @return                  属性值对象 List
     */
    protected  List doGetList(String name, Class elementType, String defaultValues) {
        String valueList = config.get(name);

        valueList = StringUtils.trimToNull(valueList);
        if (valueList == null) {
            valueList = defaultValues;
        }
        if (valueList == null || valueList.length() == 0) {
            return Collections. emptyList();
        }

        valueList = resolve(valueList);

        String[] values = StringUtils.split(valueList, ',');
        List results = new ArrayList(values.length);
        for (String value : values) {
            T object = stringAsObject(value, elementType, null);
            if (object != null) {
                results.add(object);
            }
        }
        return Collections.unmodifiableList(results);
    }

    // -----------------------------------------------------------------
    @SuppressWarnings("unchecked")
    private  T stringAsObject(String value, Class targetClass, String defaultValue) {
        value = StringUtils.trimToNull(value);
        if (value == null) {
            value = defaultValue;
        }
        if (value == null || value.length() == 0) {
            return null;
        }

        value = resolve(value);

        if (targetClass == String.class) {
            return (T) value;
        }

        if (value.startsWith("$")) {
            // this is a reference name
            return aliasNameAsObject(value, targetClass);
        }

        if (targetClass == Object.class) {
            return aliasNameAsObject(value, targetClass);
        }

        if (TypeCastUtils.support(targetClass)) {
            return TypeCastUtils.convert(value, targetClass);
        }

        if (ClassUtils.available(value)) {
            // this is a class name
            return aliasNameAsObject(value, targetClass);
        }

        throw new IllegalStateException("Cannot convert to " + targetClass + " from `" + value + "`");
    }

    protected  T aliasNameAsObject(String aliasName, Class targetClass) {
        // 1. get class name and props
        String className;
        Set propNames;

        if (aliasName.startsWith("$")) {
            // this is a reference name
            className = doGetValue(aliasName, String.class, null);
            propNames = keySet(aliasName.concat("."));
        } else {
            // this is a class name
            className = aliasName;
            propNames = null;
        }

        // 2. load class
        Class cls;

        try {
            cls = ClassLoaderUtils.loadClassEx(className);
        } catch (ClassNotFoundException e) {
            throw new IllegalStateException(e);
        }
        if (!targetClass.isAssignableFrom(cls)) {
            throw new IllegalStateException("cannot convert `" + className + "` to " + targetClass);
        }

        // 3. create instance
        return newInstance(aliasName, cls, propNames);
    }

    // -----------------------------------------------------------------

    /**
     * 根据类名或者别名,创建对象.
     *
     * @param aliasName     别名
     * @param cls           类名
     * @param propNames     要设置的属性名称
     * @return              创建的对象
     */
    @SuppressWarnings("unchecked")
    protected  T newInstance(String aliasName, Class cls, Set propNames) {
        // 1. create instance
        Object obj;

        try {
            obj = objectNewInstance(cls);
        } catch (Exception e) {
            throw new IllegalStateException(e);
        }

        // 2. set properties
        if (propNames != null && propNames.size() > 0) {
            KlassInfo klass = KlassInfo.create(cls);
            for (String propName : propNames) {
                String name = propName.substring(aliasName.length() + 1); // get setter name
                PropertyInfo p = klass.getProperty(name);
                if (p == null || !p.writable()) {
                    throw new IllegalStateException("No set" + IdentifiedNameUtils.capitalize(name) + " found in " + cls);
                }

                Class type = p.getRawType(klass);
                Object value;
                if (type == List.class || type == Collection.class || type.isArray()) {
                    Class elementType;
                    if (type.isArray()) {
                        elementType = type.getComponentType();
                    } else {
                        elementType = p.getRawComponentType(cls, 0);
                    }

                    value = doGetList(propName, elementType, null);

                    // convert list to array
                    if (type.isArray()) {
                        value = TypeCastUtils.convertToArray(value, elementType);
                    }
                } else {
                    value = doGetValue(propName, type, null);
                }

                p.set(obj, value);
            }
        }

        // 3. init
        objectInitialize(obj);

        // 4. return
        return (T) obj;
    }

    /**
     * 根据类名,创建对象.
     *
     * @param cls   类名
     * @return      创建的对象
     */
    protected  T objectNewInstance(Class cls) throws Exception {
        return cls.newInstance();
    }

    /**
     * 对象创建后,进行初始化.
     *
     * @param object    要初始化的对象
     */
    protected void objectInitialize(Object object) {
    }

    // -----------------------------------------------------------------
    private static final Pattern PLACE_HOLDER_PATTERN = Pattern.compile("\\$\\{([^}]*)\\}");

    /**
     * 根据 Config 的内容,自动解析 ${...} 的内容.
     *
     * @param value     要解析的内容
     * @return          返回解析后的内容
     */
    public String resolve(String value) {
        if (value == null || !value.contains("${")) {
            return value;
        }

        Matcher matcher = PLACE_HOLDER_PATTERN.matcher(value);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            String name = matcher.group(1);
            String val = null;
            if (name.startsWith("env:")) {
                name = name.substring(4);
                val = System.getenv(name);
            } else {
                val = doGetValue(name, String.class, null);
                if (val == null) {
                    val = System.getProperty(name);
                }
            }
            if (val == null) {
                throw new IllegalStateException("cannot find variable `" + value + "` in environment variables");
            }
            matcher.appendReplacement(sb, Matcher.quoteReplacement(val));
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy