com.sunchenbin.store.feilong.core.bean.PropertyUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.sunchenbin.store.feilong.core.bean.PropertyUtil.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.sunchenbin.store.feilong.core.bean;

import java.util.Collection;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang3.ClassUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sunchenbin.store.feilong.core.lang.ClassUtil;
import com.sunchenbin.store.feilong.core.util.Validator;

/**
 * ? {@link PropertyUtils}.
 * 
 * <h3>{@link PropertyUtils} {@link BeanUtils}:</h3>
 * 
 * <blockquote>
 * <p>
 * {@link PropertyUtils} {@link BeanUtils}??,??<br>
 * BeanUtils??"Bean",String,<br>
 * PropertyUtils??,Object
 * </p>
 * </blockquote>
 * 
 * @author feilong
 * @version 1.0.8 2014-7-21 17:45:30
 * @see org.apache.commons.beanutils.PropertyUtils
 * @see com.sunchenbin.store.feilong.core.bean.BeanUtil
 */
public final class PropertyUtil {

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

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

    /**
     * ? {@code fromObj-->toObj}.
     * 
     * <p>
     * ?:?copy?,??2Bean???ref, ??, .
     * </p>
     * 
     * <h3>?:</h3>
     * 
     * <blockquote>
     * 
     * <ol>
     * <li>includePropertyNames,? <code>fromObj</code>??,</li>
     * <li>includePropertyNames,? <code>fromObj</code>, <code>toObj</code>??,??,see
     * {@link org.apache.commons.beanutils.BeanUtilsBean#copyProperty(Object, String, Object)} Line391</li>
     * <li>Date,??converter</li>
     * </ol>
     * </blockquote>
     * 
     * 
     * <h3>:</h3>
     * 
     * <blockquote>
     * 
     * <code>
     * <pre>
    User oldUser = new User();
    oldUser.setId(5L);
    oldUser.setMoney(new BigDecimal(500000));
    oldUser.setDate(new Date());
    String[] nickName = { "feilong", "", "venusdrogon" };
    oldUser.setNickName(nickName);
        
    User newUser = new User();
        
    String[] strs = { "date", "money", "nickName" };
    PropertyUtil.copyProperties(newUser, oldUser, strs);
    LOGGER.info(JsonUtil.format(newUser));s(enterpriseSales,enterpriseSales_form,new String[]{&quot;enterpriseName&quot;,&quot;linkMan&quot;,&quot;phone&quot;});
     *
     * 
     *  :
     * 
     * {
    "userAddresseList": [],
    "userAddresses": [],
    "date": "2015-09-06 13:27:43",
    "password": "",
    "id": 0,
    "nickName":         [
        "feilong",
        "",
        "venusdrogon"
    ],
    "age": 0,
    "name": "feilong",
    "money": 500000,
    "attrMap": null,
    "userInfo": {"age": 0},
    "loves": []
    }
     * 
     * </pre>
     * </code>
     * 
     * </blockquote>
     * 
     * 
     * <h3>{@link BeanUtils#copyProperties(Object, Object)} {@link PropertyUtils#copyProperties(Object, Object)}</h3>
     * 
     * <blockquote>
     * <ul>
     * <li>{@link BeanUtils#copyProperties(Object, Object)}??????,????</li>
     * <li>{@link PropertyUtils#copyProperties(Object, Object)} ???,??JavaBean?????,???,???,.</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
     * {@link <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>
     *             null or empty , {@link PropertyUtils#copyProperties(Object, Object)}
     * @see #setProperty(Object, String, Object)
     * 
     * @see com.sunchenbin.store.feilong.core.bean.BeanUtil#copyProperties(Object, Object, String...)
     * 
     * @see org.apache.commons.beanutils.PropertyUtilsBean#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>
     * @since 1.4.1
     */
    public static void copyProperties(Object toObj, Object fromObj, String... includePropertyNames) {
        if (null == toObj) {
            throw new NullPointerException("No destination bean/toObj specified");
        }
        if (null == fromObj) {
            throw new NullPointerException("No origin bean/fromObj specified");
        }

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

    /**
     * <code>bean</code> <span style="color:green">?</span>,??/Map.
     * 
     * <p>
     * ???class,Object??,classjava.lang.Object
     * </p>
     * 
     * <h3>?:</h3>
     * 
     * <blockquote>
     * <ol>
     * <li>?bean class {@link java.beans.PropertyDescriptor}</li>
     * <li>, {@link java.beans.PropertyDescriptor#getReadMethod()}</li>
     * <li> name and {@link org.apache.commons.beanutils.PropertyUtilsBean#getProperty(Object, String)} map</li>
     * </ol>
     * </blockquote>
     *
     * @param bean
     *            Bean whose properties are to be extracted
     * @return The set of properties for the bean
     * @see org.apache.commons.beanutils.BeanUtils#describe(Object)
     * @see org.apache.commons.beanutils.PropertyUtils#describe(Object)
     * @see com.sunchenbin.store.feilong.core.bean.BeanUtil#describe(Object)
     */
    public static Map<String, Object> describe(Object bean) {
        try {
            //Return the entire set of properties for which the specified bean provides a read method.
            return PropertyUtils.describe(bean);
        } catch (Exception e) {
            LOGGER.error(e.getClass().getName(), e);
            throw new BeanUtilException(e);
        }
    }

    /**
     *  {@link PropertyUtils#setProperty(Object, String, Object)} ?(<b>??</b>).
     *
     * @param bean
     *            Bean whose property is to be modified
     * @param propertyName
     *            Possibly indexed and/or nested name of the property to be modified
     * @param value
     *            Value to which this property is to be set
     * @see org.apache.commons.beanutils.BeanUtils#setProperty(Object, String, Object)
     * @see org.apache.commons.beanutils.PropertyUtils#setProperty(Object, String, Object)
     * @see com.sunchenbin.store.feilong.core.bean.BeanUtil#setProperty(Object, String, Object)
     */
    public static void setProperty(Object bean, String propertyName, Object value) {
        try {
            //Set the value of the specified property of the specified bean, no matter which property reference format is used, with no type conversions.
            // PropertyUtilsBeanUtils,?????
            PropertyUtils.setProperty(bean, propertyName, value);
        } catch (Exception e) {
            LOGGER.error(e.getClass().getName(), e);
            throw new BeanUtilException(e);
        }
    }

    // [start] getProperty

    /**
     *  {@link PropertyUtils#getProperty(Object, String)} ?.
     *
     * @param <T>
     *            the generic type
     * @param bean
     *            Bean whose property is to be extracted
     * @param propertyName
     *            Possibly indexed and/or nested name of the property to be extracted
     * @return {@link PropertyUtils#getProperty(Object, String)} ?
     * @see com.sunchenbin.store.feilong.core.bean.BeanUtil#getProperty(Object, String)
     * @see org.apache.commons.beanutils.BeanUtils#getProperty(Object, String)
     * @see org.apache.commons.beanutils.PropertyUtils#getProperty(Object, String)
     * @see org.apache.commons.beanutils.PropertyUtilsBean
     */
    @SuppressWarnings("unchecked")
    public static <T> T getProperty(Object bean, String propertyName) {
        //Return the value of the specified property of the specified bean, no matter which property reference format is used, with no type conversions.
        //For more details see PropertyUtilsBean.
        try {
            return (T) PropertyUtils.getProperty(bean, propertyName);
        } catch (Exception e) {
            LOGGER.error(e.getClass().getName(), e);
            throw new BeanUtilException(e);
        }
    }

    // [end]

    /**
     *  <code>Object obj</code>,.
     * 
     * <h3>??:</h3>
     * 
     * <blockquote>
     * <ol>
     * <li>{@code if ClassUtil.isInstance(findValue, toBeFindedClassType)  findValue}</li>
     * <li>{@code isPrimitiveOrWrapper},{@code CharSequence},{@code Collection},{@code Map}</li>
     * <li> {@link PropertyUtil#describe(Object)} ?</li>
     * </ol>
     * </blockquote>
     *
     * @param <T>
     *            the generic type
     * @param obj
     *            ?
     * @param toBeFindedClassType
     *            the to be finded class type
     * @return a value of the given type found if there is a clear match,or {@code null} if none such value found
     * @see "org.springframework.util.CollectionUtils#findValueOfType(Collection, Class)"
     * @since 1.4.1
     */
    @SuppressWarnings("unchecked")
    public static <T> T findValueOfType(Object obj, Class<T> toBeFindedClassType) {
        if (Validator.isNullOrEmpty(obj)) {
            return null;
        }

        if (null == toBeFindedClassType) {
            throw new NullPointerException("toBeFindedClassType can't be null/empty!");
        }

        if (ClassUtil.isInstance(obj, toBeFindedClassType)) {
            return (T) obj;
        }

        //command ?  string int,list map
        //,?? findedClassType
        boolean canFindType = !ClassUtils.isPrimitiveOrWrapper(toBeFindedClassType)//
                && !ClassUtil.isInstance(obj, CharSequence.class)//
                && !ClassUtil.isInstance(obj, Collection.class) //
                && !ClassUtil.isInstance(obj, Map.class) //
        ;

        if (!canFindType) {
            return null;
        }

        //******************************************************************************
        Map<String, Object> describe = describe(obj);

        for (Map.Entry<String, Object> entry : describe.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();

            if (null != value && !"class".equals(key)) {
                //?
                T t = findValueOfType(value, toBeFindedClassType);
                if (null != t) {
                    return t;
                }
            }
        }
        return null;
    }
}