com.feilong.core.bean.BeanUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.feilong.core.bean.BeanUtil.java

Source

/*
 * Copyright (C) 2008 feilong
 *
 * 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.feilong.core.bean;

import static java.util.Collections.emptyMap;

import java.lang.reflect.Field;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.ConvertUtilsBean;
import org.apache.commons.beanutils.Converter;
import org.apache.commons.beanutils.DynaBean;
import org.apache.commons.beanutils.LazyDynaBean;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.beanutils.converters.ArrayConverter;
import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static com.feilong.core.Validator.isNotNullOrEmpty;
import static com.feilong.core.Validator.isNullOrEmpty;
import static com.feilong.core.util.MapUtil.newHashMap;

/**
 *  {@link org.apache.commons.beanutils.BeanUtils}??.
 * 
 * <p>
 * ? checkedException  ?? {@link BeanUtilException}
 * </p>
 * 
 * <h3>{@link PropertyUtils} {@link BeanUtils}:</h3>
 * 
 * <blockquote>
 * 
 * <pre class="code">
 * BeanUtils.setProperty(pt1, &quot;x&quot;, &quot;9&quot;); // 9String
 * PropertyUtils.setProperty(pt1, &quot;x&quot;, 9); // int
 * // BeanUtilsPropertyUtils,?int,??
 * </pre>
 * 
 * <p>
 * {@link PropertyUtils} {@link BeanUtils}??,??.<br>
 * BeanUtils??"Bean",String,<br>
 * PropertyUtils??,Object.
 * </p>
 * </blockquote>
 * 
 * <h3> {@link BeanUtils#copyProperty(Object, String, Object) copyProperty}  {@link BeanUtils#setProperty(Object, String, Object)
 * setProperty}:</h3>
 * 
 * <blockquote>
 * 
 * <pre class="code">
 * ,:
 * copyProperty ??bean,?beansetter
 * copyProperty ??beanMap,?beanMapsetter
 * 
 * ?bean?,{@link BeanUtils#copyProperty(Object, String, Object)}?;
 * {@link BeanUtils#setProperty(Object, String, Object)}  {@link BeanUtils#populate(Object,Map)},?populate(),?override {@link BeanUtils#setProperty(Object, String, Object)}.
 * ,?,{@link BeanUtils#setProperty(Object, String, Object)}???.
 * </pre>
 * 
 * </blockquote>
 * 
 * <h3><a name="propertyName">propertyName</a></h3>
 * 
 * <blockquote>
 * getPropertysetProperty,?2?,JavaBean,????.
 * 
 * <pre class="code">
 * Company c = new Company();
 * c.setName("Simple");
 * </pre>
 * 
 * <ul>
 * <li>
 * <p>
 * <b>Simple(?,String Int)</b>
 * </p>
 * 
 * <pre class="code">
 * Simple,?????
 * LOGGER.debug(BeanUtils.getProperty(c, "name"));
 * </pre>
 * 
 * </li>
 * 
 * <li>
 * <p>
 * <b>Map</b>
 * </p>
 * Map,?"??(key)"?
 * 
 * <pre class="code">
 * LOGGER.debug(BeanUtils.getProperty(c, "address (A2)"));
 * Map am = new HashMap();
 * am.put("1", "234-222-1222211");
 * am.put("2", "021-086-1232323");
 * BeanUtils.setProperty(c, "telephone", am);
 * LOGGER.debug(BeanUtils.getProperty(c, "telephone (2)"));
 * </pre>
 * 
 * </li>
 * <li>
 * <p>
 * <b>(Indexed),  arrayList</b>
 * </p>
 * 
 * Indexed,"??[]",?ArrayList???.
 * 
 * <pre class="code">
 * LOGGER.debug(BeanUtils.getProperty(c, "otherInfo[2]"));
 * BeanUtils.setProperty(c, "product[1]", "NOTES SERVER");
 * LOGGER.debug(BeanUtils.getProperty(c, "product[1]"));
 * </pre>
 * 
 * </li>
 * 
 * <li>
 * <p>
 * <b>?(nest)</b>
 * </p>
 * 
 * <pre class="code">
 * 3????
 * LOGGER.debug(BeanUtils.getProperty(c, "employee[1].name"));
 * </pre>
 * 
 * </li>
 * </ul>
 * </blockquote>
 * 
 * @author <a href="http://feitianbenyue.iteye.com/">feilong</a>
 * @see com.feilong.core.bean.PropertyUtil
 * 
 * @see java.beans.BeanInfo
 * @see java.beans.PropertyDescriptor
 * @see java.beans.MethodDescriptor
 * 
 * @see org.apache.commons.beanutils.BeanUtils
 * @see org.apache.commons.beanutils.Converter
 * @see org.apache.commons.beanutils.converters.DateConverter
 * @see org.apache.commons.beanutils.converters.DateTimeConverter
 * @see org.apache.commons.beanutils.converters.AbstractConverter
 * 
 * @see org.apache.commons.beanutils.ConvertUtils#register(org.apache.commons.beanutils.Converter, Class)
 * 
 * @see org.apache.commons.beanutils.ConvertUtilsBean#registerPrimitives(boolean)
 * @see org.apache.commons.beanutils.ConvertUtilsBean#registerStandard(boolean, boolean)
 * @see org.apache.commons.beanutils.ConvertUtilsBean#registerOther(boolean)
 * @see org.apache.commons.beanutils.ConvertUtilsBean#registerArrays(boolean, int)
 * 
 * @see "org.springframework.beans.BeanUtils"
 * 
 * @since 1.0.0
 */
public final class BeanUtil {

    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory.getLogger(BeanUtil.class);

    /** Don't let anyone instantiate this class. */
    private BeanUtil() {
        //AssertionError?. ?????. ???.
        //see Effective Java 2nd
        throw new AssertionError("No " + getClass().getName() + " instances for you!");
    }

    static {
        //?.
        initConverters();
    }

    /**
     * ?.
     * 
     * <h3>?:</h3>
     * 
     * <blockquote>
     * <p>
     * ??, {@link org.apache.commons.beanutils.ConvertUtilsBean#register(boolean, boolean, int) ConvertUtilsBean.register(boolean,
     * boolean, int)}<br>
     * ??,beanUtils,????<br>
     * ?,,? {@link org.apache.commons.beanutils.Converter},<br>
     *    ??:
     * </p>
     * 
     * <ul>
     * <li>{@link ConvertUtilsBean#registerPrimitives(boolean) registerPrimitives(boolean throwException)}</li>
     * <li>{@link ConvertUtilsBean#registerStandard(boolean,boolean) registerStandard(boolean throwException, boolean defaultNull);}</li>
     * <li>{@link ConvertUtilsBean#registerOther(boolean) registerOther(boolean throwException);}</li>
     * <li>{@link ConvertUtilsBean#registerArrays(boolean,int) registerArrays(boolean throwException, int defaultArraySize);}</li>
     * </ul>
     * 
     *  register,{@link org.apache.commons.beanutils.ConvertUtilsBean#deregister(Class) ConvertUtilsBean.deregister(Class)}
     * </blockquote>
     * 
     * <h3>:</h3>
     * 
     * <blockquote>
     * 
     * <pre class="code">
     * 
     * MyObject myObject = new MyObject();
     * myObject.setId(3l);
     * myObject.setName(&quot;My Name&quot;);
     * 
     * ConvertUtilsBean cub = new ConvertUtilsBean();
     * cub.deregister(Long.class);
     * cub.register(new MyLongConverter(), Long.class);
     * 
     * LOGGER.debug(cub.lookup(Long.class));
     * 
     * BeanUtilsBean bub = new BeanUtilsBean(cub, new PropertyUtilsBean());
     * 
     * LOGGER.debug(bub.getProperty(myObject, &quot;name&quot;));
     * LOGGER.debug(bub.getProperty(myObject, &quot;id&quot;));
     * 
     * </pre>
     * 
     * </blockquote>
     *
     * @since 1.5.0
     */
    private static void initConverters() {
        //XXX initConverters?
        BeanUtilsBean beanUtilsBean = BeanUtilsBean.getInstance();
        ConvertUtilsBean convertUtils = beanUtilsBean.getConvertUtils();

        boolean throwException = false;
        boolean defaultNull = true;
        int defaultArraySize = 10;
        convertUtils.register(throwException, defaultNull, defaultArraySize);
    }

    /**
     * {@link ConvertUtils#register(Converter, Class)}?.
     * 
     * <h3>:</h3>
     * 
     * <blockquote>
     * <p>
     * ??,static???,?register converter,<br>
     * ?,ConvertUtilsConverter,?,<br>
     * :
     * </p>
     * 
     * <pre class="code">
     * ConvertUtils.register(new DateLocaleConverter(Locale.US, DatePattern.TO_STRING_STYLE), Date.class)
     * 
     * User user1 = new User();
     * user1.setDate(new Date());
     * 
     * User user2 = new User();
     * BeanUtil.copyProperties(user2, user1, "date");
     * </pre>
     * 
     * <p>
     *  {@link DateLocaleConverter} ?? static ? {@link org.apache.commons.beanutils.converters.DateConverter} ?
     * </p>
     * 
     * <p>
     * ,<span style="color:red">,?commons-bean {@link ConvertUtils#register(Converter, Class)}</span> ,<br>
     * ?static??,? {@link Converter} ??
     * </p>
     * </blockquote>
     *
     * @param converter
     *            the converter
     * @param klass
     *            the klass
     * @see org.apache.commons.beanutils.ConvertUtils#register(Converter, Class)
     * @since 1.5.0
     */
    public static void register(Converter converter, Class<?> klass) {
        ConvertUtils.register(converter, klass);
    }

    // [start] copyProperties

    /**
     * <code class="code">fromObj</code>,? <code>toObj</code>.
     * 
     * <h3>?:</h3>
     * 
     * <blockquote>
     * <ol>
     * <li>?copy <span style="color:red">?</span>,??2Bean???ref,??, .</li>
     * <li> {@link BeanUtils#copyProperties(Object, Object)},{@code Object--->String--->Object}?,<br>
     * ?copy?,<span style="color:red"></span>,
     * {@link PropertyUtil#copyProperties(Object, Object, String...)}</li>
     * </ol>
     * </blockquote>
     * 
     * <h3>??:</h3>
     * <blockquote>
     * <p>
     * <code>includePropertyNames</code>?, {@link BeanUtils#copyProperties(Object, Object)}<br>
     * ?{@link #getProperty(Object, String)} ?{@link #setProperty(Object, String, Object)} <code>toObj</code>
     * </p>
     * </blockquote>
     * 
     * <h3>?:</h3>
     * 
     * <blockquote>
     * 
     * <ol>
     * <li><code>includePropertyNames</code>,? <code>fromObj</code>??,</li>
     * <li><code>includePropertyNames</code>,? <code>fromObj</code>, <code>toObj</code>??,??,see
     * {@link BeanUtilsBean#copyProperty(Object, String, Object)} Line391</li>
     * </ol>
     * </blockquote>
     * 
     * 
     * <h3>:</h3>
     * 
     * <blockquote>
     * 
     * <pre class="code">
     * pojo: useruserForm ?"enterpriseName","linkMan","phone"
     * 
     * :
     * .....
     * user.setEnterpriseName(userForm.getEnterpriseName());
     * user.setLinkMan(userForm.getLinkMan());
     * user.setPhone(userForm.getPhone());
     * ......
     * 
     * ,?
     * BeanUtil.copyProperties(user,userForm,"enterpriseName","linkMan","phone");
     * </pre>
     * 
     * </blockquote>
     * 
     * 
     * <h3> {@link Converter}:</h3>
     * 
     * <blockquote>
     * <p>
     *  {@link java.util.Date} ?copy,?? {@link #register(Converter, Class)}:<br>
     * 
     * <code>BeanUtil.register(new DateLocaleConverter(Locale.US, DatePattern.TO_STRING_STYLE),Date.class);</code>
     * 
     * <br>
     * ,?? {@link #register(Converter, Class)}
     * </p>
     * </blockquote>
     * 
     * 
     * <h3>{@link BeanUtils#copyProperties(Object, Object)} {@link PropertyUtils#copyProperties(Object, Object)}</h3>
     * 
     * <blockquote>
     * <ul>
     * <li>{@link BeanUtils#copyProperties(Object, Object)} ???,??JavaBean?????,???,
     * {@link PropertyUtils#copyProperties(Object, Object)}??,.</li>
     * <li>commons-beanutils v1.9.0? BeanUtils?? null,PropertyUtils?? null.<br>
     * (<b>:</b>commons-beanutils v1.9.0+?,BeanUtilsBean.copyProperties() no longer throws a ConversionException for null properties
     * of certain data types),?,??commons-beanutils
     * <a href="http://commons.apache.org/proper/commons-beanutils/javadocs/v1.9.2/RELEASE-NOTES.txt">RELEASE-NOTES.txt</a></li>
     * </ul>
     * </blockquote>
     *
     * @param toObj
     *            
     * @param fromObj
     *            
     * @param includePropertyNames
     *            ???,(can be nested/indexed/mapped/combo)<br>
     *            nullempty , {@link BeanUtils#copyProperties(Object, Object)}
     * @throws NullPointerException
     *              <code>toObj</code> null, <code>fromObj</code> null
     * @throws BeanUtilException
     *             api,?{@link BeanUtilException}
     * @see #setProperty(Object, String, Object)
     * @see org.apache.commons.beanutils.BeanUtilsBean#copyProperties(Object, Object)
     * @see <a href="http://www.cnblogs.com/kaka/archive/2013/03/06/2945514.html">Bean??(Apache BeanUtils?PropertyUtils,Spring
     *      BeanUtils,Cglib BeanCopier)</a>
     */
    //XXX add excludePropertyNames support
    public static void copyProperties(Object toObj, Object fromObj, String... includePropertyNames) {
        Validate.notNull(toObj, "toObj [destination bean] not specified!");
        Validate.notNull(fromObj, "fromObj [origin bean] not specified!");

        if (isNullOrEmpty(includePropertyNames)) {
            try {
                BeanUtils.copyProperties(toObj, fromObj);
                return;
            } catch (Exception e) {
                LOGGER.error(e.getClass().getName(), e);
                throw new BeanUtilException(e);
            }
        }
        for (String propertyName : includePropertyNames) {
            String value = getProperty(fromObj, propertyName);
            setProperty(toObj, propertyName, value);
        }
    }

    // [end]

    // [start] setProperty

    /**
     *  {@link BeanUtils#setProperty(Object, String, Object)} ?(<b>?</b>).
     * 
     * <p>
     * BeanUtils??,???(?)
     * </p>
     *
     * @param bean
     *            Bean on which setting is to be performed
     * @param propertyName
     *            Property name (can be nested/indexed/mapped/combo),??<a href="#propertyName">propertyName</a>
     * @param value
     *            Value to be set
     * @throws BeanUtilException
     *             ,?{@link BeanUtilException}
     * @see org.apache.commons.beanutils.BeanUtils#setProperty(Object, String, Object)
     * @see org.apache.commons.beanutils.BeanUtilsBean#setProperty(Object, String, Object)
     * @see org.apache.commons.beanutils.PropertyUtils#setProperty(Object, String, Object)
     * @see com.feilong.core.bean.PropertyUtil#setProperty(Object, String, Object)
     */
    public static void setProperty(Object bean, String propertyName, Object value) {
        try {
            BeanUtils.setProperty(bean, propertyName, value);
        } catch (Exception e) {
            LOGGER.error(e.getClass().getName(), e);
            throw new BeanUtilException(e);
        }
    }

    // [end]

    // [start] getProperty

    /**
     *  {@link BeanUtils#getProperty(Object, String)} ?,?care,? {@link String}.
     *
     * @param bean
     *            bean
     * @param propertyName
     *            ?? (can be nested/indexed/mapped/combo),?? <a href="#propertyName">propertyName</a>
     * @return {@link BeanUtils#getProperty(Object, String)} ?
     * @throws NullPointerException
     *              <code>bean</code> null, <code>propertyName</code> null
     * @throws IllegalArgumentException
     *              <code>propertyName</code> blank
     * @throws BeanUtilException
     *              {@link BeanUtils#getProperty(Object, String)},?{@link BeanUtilException}
     * @see org.apache.commons.beanutils.BeanUtils#getProperty(Object, String)
     * @see org.apache.commons.beanutils.PropertyUtils#getProperty(Object, String)
     * @see com.feilong.core.bean.PropertyUtil#getProperty(Object, String)
     */
    public static String getProperty(Object bean, String propertyName) {
        Validate.notNull(bean, "bean can't be null!");
        Validate.notBlank(propertyName, "propertyName can't be blank!");
        try {
            return BeanUtils.getProperty(bean, propertyName);
        } catch (Exception e) {
            LOGGER.error(e.getClass().getName(), e);
            throw new BeanUtilException(e);
        }
    }

    // [end]

    // [start] cloneBean

    /**
     * {@link BeanUtils#cloneBean(Object)}.
     * 
     * <p>
     * bean,???bean,?bean {@link Cloneable}? .
     * </p>
     * 
     * <h3>?:</h3>
     * <blockquote>
     * 
     * <ol>
     * <li>clone</li>
     * <li>?? <b>getPropertyUtils().copyProperties(newBean, bean)</b>;?<b>?,clone</b><br>
     * ???,???(?),?clone,,?
     * </li>
     * <li> {@link java.lang.Class#newInstance() Class.newInstance()}?,?clone<b>?</b>,?
     * {@link java.lang.InstantiationException InstantiationException}</li>
     * <li>?clone list,empty list,??
     * <a href="https://issues.apache.org/jira/browse/BEANUTILS-471">BeanUtils.cloneBean with List is broken</a></li>
     * </ol>
     * </blockquote>
     * 
     * <h3>clone:</h3>
     * 
     * <blockquote>
     * <p>
     * ?clone,? {@link org.apache.commons.lang3.SerializationUtils#clone(java.io.Serializable) SerializationUtils.clone},??
     * </p>
     * </blockquote>
     *
     * @param <T>
     *            the generic type
     * @param bean
     *            Bean to be cloned
     * @return the cloned bean (? ,clone)
     * @throws NullPointerException
     *              <code>bean</code> null
     * @throws BeanUtilException
     *             api,?{@link BeanUtilException}
     * @see org.apache.commons.beanutils.BeanUtils#cloneBean(Object)
     * @see org.apache.commons.beanutils.PropertyUtilsBean#copyProperties(Object, Object)
     * @see org.apache.commons.lang3.SerializationUtils#clone(java.io.Serializable)
     * @see org.apache.commons.lang3.ObjectUtils#clone(Object)
     * @see org.apache.commons.lang3.ObjectUtils#cloneIfPossible(Object)
     */
    @SuppressWarnings("unchecked")
    public static <T> T cloneBean(T bean) {
        Validate.notNull(bean, "bean can't be null!");
        try {
            return (T) BeanUtils.cloneBean(bean);
        } catch (Exception e) {
            LOGGER.error(e.getClass().getName(), e);
            throw new BeanUtilException(e);
        }
    }

    // [end]

    // [start] populate() properties/map?bean

    /**
     * properties/map? <code>populate</code> <b>()</b>bean.
     * 
     * <p>
     * Map{@code <Key,value>}(StringString[])?bean,Keybean??.
     * </p>
     * 
     * <h3>:</h3>
     * <blockquote>
     * 
     * <pre class="code">
     * User user = new User();
     * user.setId(5L);
     * 
     * Map{@code <String, Object>} properties = new HashMap{@code <String, Object>}();
     * properties.put("id", 8L);
     * 
     * BeanUtil.populate(user, properties);
     * LOGGER.info(JsonUtil.format(user));
     * </pre>
     * 
     * <b>:</b>
     * 
     * <pre class="code">
     * {
     * "date": null,
     * "id": 8,
     * "loves": []
     * }
     * </pre>
     * 
     * </blockquote>
     * 
     * 
     * <h3>?:</h3>
     * 
     * <blockquote>
     * <p>
     * apachejavadoc,?http?,???.?? {@link #copyProperties(Object, Object, String...)}
     * </p>
     * </blockquote>
     * 
     * 
     * <h3>? {@link BeanUtilsBean#populate(Object, Map)}:</h3>
     * 
     * <blockquote>
     * <p>
     * map, {@link BeanUtilsBean#setProperty(Object, String, Object)} , <code>bean</code>
     * </p>
     * </blockquote>
     *
     * @param <T>
     *            the generic type
     * @param bean
     *            JavaBean whose properties are being populated
     * @param properties
     *            Map keyed by property name,with the corresponding (String or String[]) value(s) to be set
     * @return the t
     * @throws NullPointerException
     *              <code>bean</code> null, <code>properties</code> null
     * @throws BeanUtilException
     *             {@link BeanUtils#populate(Object, Map)},?{@link BeanUtilException}
     * @see org.apache.commons.beanutils.BeanUtils#populate(Object, Map)
     */
    public static <T> T populate(T bean, Map<String, ?> properties) {
        Validate.notNull(bean, "bean can't be null/empty!");
        Validate.notNull(properties, "properties can't be null/empty!");

        try {
            BeanUtils.populate(bean, properties);
            return bean;
        } catch (Exception e) {
            throw new BeanUtilException(e);
        }
    }

    /**
     *  alias value map <code>populate</code> <b>()</b> <code>aliasBean</code>.
     * 
     * <h3>:</h3>
     * 
     * <blockquote>
     * <p>
     * {@link BeanUtil} populate,{@link #populate(Object, Map)} ,? mapkey  bean??<br>
     * , map key <b>"memcached.alivecheck"</b> (?properties ?), <b>"ALIVECHECK"</b> (?? xml??)<br>
     * bean??? java bean ??, <b>"aliveCheck"</b>, {@link #populate(Object, Map)} <br>
     * </p>
     * 
     * <p>
     * ? {@link #populateAliasBean(Object, Map)}~~
     * </p>
     * </blockquote>
     * 
     * <h3>:</h3>
     * 
     * <blockquote>
     * 
     * <p>
     * <b>aliasAndValueMap</b>?:
     * </p>
     * 
     * <pre class="code">
     * {
     * "memcached.alivecheck": "false",
     * "memcached.expiretime": "180",
     * "memcached.initconnection": "10",
     * "memcached.maintSleep": "30",
     * "memcached.maxconnection": "250",
     * "memcached.minconnection": "5",
     * "memcached.nagle": "false",
     * "memcached.poolname": "sidsock2",
     * "memcached.serverlist": "172.20.31.23:11211,172.20.31.22:11211",
     * "memcached.serverweight": "2",
     * "memcached.socketto": "3000"
     * }
     * 
     * </pre>
     * 
     * <p>
     * <b>aliasBean</b>?:
     * </p>
     * 
     * <pre class="code">
     * 
     * public class DangaMemCachedConfig{
     * 
     *     <span style="color:green">//** The serverlist.</span>
     *     &#64;Alias(name = "memcached.serverlist",sampleValue = "172.20.31.23:11211,172.20.31.22:11211")
     *     private String[] serverList;
     * 
     *     <span style="color:green">//@Alias(name = "memcached.poolname",sampleValue = "sidsock2")</span>
     *     private String poolName;
     * 
     *     <span style="color:green">//** The expire time ??.</span>
     *     &#64;Alias(name = "memcached.expiretime",sampleValue = "180")
     *     private Integer expireTime;
     * 
     *     <span style="color:green">//** ??. </span>
     *     &#64;Alias(name = "memcached.serverweight",sampleValue = "2,1")
     *     private Integer[] weight;
     * 
     *     <span style="color:green">//** The init connection. </span>
     *     &#64;Alias(name = "memcached.initconnection",sampleValue = "10")
     *     private Integer initConnection;
     * 
     *     <span style="color:green">//** The min connection.</span>
     *     &#64;Alias(name = "memcached.minconnection",sampleValue = "5")
     *     private Integer minConnection;
     * 
     *     <span style="color:green">//** The max connection. </span>
     *     &#64;Alias(name = "memcached.maxconnection",sampleValue = "250")
     *     private Integer maxConnection;
     * 
     *     <span style="color:green">//** ?,?30?,??.</span>
     *     &#64;Alias(name = "memcached.maintSleep",sampleValue = "30")
     *     private Integer maintSleep;
     * 
     *     <span style="color:green">//** . </span>
     *     &#64;Alias(name = "memcached.nagle",sampleValue = "false")
     *     private Boolean nagle;
     * 
     *     <span style="color:green">//** ?.</span>
     *     &#64;Alias(name = "memcached.socketto",sampleValue = "3000")
     *     private Integer socketTo;
     * 
     *     <span style="color:green">//** The alive check.</span>
     *     &#64;Alias(name = "memcached.alivecheck",sampleValue = "false")
     *     private Boolean aliveCheck;
     * 
     *     <span style="color:green">//setter getter </span>
     * }
     * 
     * </pre>
     * 
     * <b>
     * ??:
     * </b>
     * 
     * <pre class="code">
     * Map{@code <String, String>} readPropertiesToMap = ResourceBundleUtil.readPropertiesToMap("memcached");
     * 
     * DangaMemCachedConfig dangaMemCachedConfig = new DangaMemCachedConfig();
     * BeanUtil.populateAliasBean(dangaMemCachedConfig, readPropertiesToMap);
     * LOGGER.debug(JsonUtil.format(dangaMemCachedConfig));
     * </pre>
     * 
     * <b>:</b>
     * 
     * <pre class="code">
    {
    "maxConnection": 250,
    "expireTime": 180,
    "serverList":         [
        "172.20.31.23",
        "11211",
        "172.20.31.22",
        "11211"
    ],
    "weight": [2],
    "nagle": false,
    "initConnection": 10,
    "aliveCheck": false,
    "poolName": "sidsock2",
    "maintSleep": 30,
    "socketTo": 3000,
    "minConnection": 5
    }
     * </pre>
     * 
     * <p>
     * ?,? serverList  ["172.20.31.23:11211","172.20.31.22:11211"],??,<br>
     * , {@link ArrayConverter} ? allowedChars ? <code>'.', '-'</code>,??
     * </p>
     * 
     * <p>
     * ?:
     * </p>
     *
     * <pre class="code">
     * Map{@code <String, String>} readPropertiesToMap = ResourceBundleUtil.readPropertiesToMap("memcached");
     * 
     * DangaMemCachedConfig dangaMemCachedConfig = new DangaMemCachedConfig();
     * 
     * <span style="color:blue">ArrayConverter arrayConverter = new ArrayConverter(String[].class, new StringConverter(), 2);</span>
     * <span style="color:blue">char[] allowedChars = { ':' };</span>
     * <span style="color:blue">arrayConverter.setAllowedChars(allowedChars);</span>
     * <span style="color:blue">BeanUtil.register(arrayConverter, String[].class);</span>
     * 
     * BeanUtil.populateAliasBean(dangaMemCachedConfig, readPropertiesToMap);
     * LOGGER.debug(JsonUtil.format(dangaMemCachedConfig));
     * </pre>
     * 
     * <b>:</b>
     * 
     * <pre class="code">
    {
    "maxConnection": 250,
    "expireTime": 180,
    "serverList":         [
        "172.20.31.23:11211",
        "172.20.31.22:11211"
    ],
    "weight": [2],
    "nagle": false,
    "initConnection": 10,
    "aliveCheck": false,
    "poolName": "sidsock2",
    "maintSleep": 30,
    "socketTo": 3000,
    "minConnection": 5
    }
     * </pre>
     * 
     * </blockquote>
     * 
     * @param <T>
     *            the generic type
     * @param aliasBean
     *            the bean
     * @param aliasAndValueMap
     *            the key and value map
     * @return  <code>aliasAndValueMap</code> nullempty, <code>bean</code><br>
     *          <code>alias name</code> ?<code>aliasAndValueMap</code>,emty,? <code>aliasBean</code>
     * @throws NullPointerException
     *              <code>bean</code> null
     * @since 1.8.1
     */
    public static <T> T populateAliasBean(T aliasBean, Map<String, ?> aliasAndValueMap) {
        Validate.notNull(aliasBean, "aliasBean can't be null!");
        if (isNullOrEmpty(aliasAndValueMap)) {
            return aliasBean;
        }
        Map<String, String> propertyNameAndAliasMap = buildPropertyNameAndAliasMap(aliasBean.getClass());
        for (Map.Entry<String, String> entry : propertyNameAndAliasMap.entrySet()) {
            String alias = entry.getValue();
            Object value = aliasAndValueMap.get(alias);
            if (isNotNullOrEmpty(value)) {
                setProperty(aliasBean, entry.getKey(), value);
            }
        }
        return aliasBean;
    }

    /**
     * ??? klass {@link Alias} , ?? {@link Alias#name()} ?map .
     *
     * @param klass
     *            the klass
     * @return <code>klass</code>  {@link Alias} , {@link Collections#emptyMap()}
     * @throws NullPointerException
     *              <code>klass</code> null
     * @since 1.8.1
     */
    private static Map<String, String> buildPropertyNameAndAliasMap(Class<?> klass) {
        Validate.notNull(klass, "klass can't be null!");
        List<Field> aliasFieldsList = FieldUtils.getFieldsListWithAnnotation(klass, Alias.class);
        if (isNullOrEmpty(aliasFieldsList)) {
            return emptyMap();
        }
        //??key
        Map<String, String> propertyNameAndAliasMap = newHashMap(aliasFieldsList.size());
        for (Field field : aliasFieldsList) {
            Alias alias = field.getAnnotation(Alias.class);
            propertyNameAndAliasMap.put(field.getName(), alias.name());
        }
        return propertyNameAndAliasMap;
    }

    // [end]

    /**
     * New dyna bean.
     * 
     * <p>
     * {@link LazyDynaBean}????DynaClass?LazyDynaBean??<br>
     * {@link LazyDynaBean}???mapkey-value pairLazyDynaBeanmapmetadatametadata<br>
     * 
     * ?, {@link org.apache.commons.beanutils.LazyDynaClass}
     * </p>
     * 
     * <h3>:</h3>
     * 
     * <blockquote>
     * 
     * <pre class="code">
     * 
     * DynaBean newDynaBean = BeanUtil.newDynaBean(toMap(//
     *                 Pair.of("address", (Object) new HashMap()),
     *                 Pair.of("firstName", (Object) "Fred"),
     *                 Pair.of("lastName", (Object) "Flintstone")));
     * LOGGER.debug(JsonUtil.format(newDynaBean));
     * 
     * </pre>
     * 
     * <b>:</b>
     * 
     * <pre class="code">
     * {
    "address": {},
    "firstName": "Fred",
    "lastName": "Flintstone"
    }
     * </pre>
     * 
     * </blockquote>
     *
     * @param valueMap
     *            the value map
     * @return the dyna bean
     * @see org.apache.commons.beanutils.LazyDynaBean
     * @throws NullPointerException
     *              <code>valueMap</code> null, mapkeynull
     * @since 1.8.1
     */
    public static DynaBean newDynaBean(Map<String, ?> valueMap) {
        Validate.notNull(valueMap, "valueMap can't be null!");

        LazyDynaBean lazyDynaBean = new LazyDynaBean();
        for (Map.Entry<String, ?> entry : valueMap.entrySet()) {
            Validate.notBlank(entry.getKey(), "entry.getKey() can't be blank!");
            lazyDynaBean.set(entry.getKey(), entry.getValue());
        }
        return lazyDynaBean;
    }
}