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

com.feilong.core.bean.PropertyValueObtainer Maven / Gradle / Ivy

Go to download

feilong is a suite of core and expanded libraries that include utility classes, http, excel,cvs, io classes, and much much more.

There is a newer version: 4.3.0
Show newest version
/*
 * 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 com.feilong.core.bean.ConvertUtil.convert;
import static com.feilong.core.bean.PropertyDescriptorUtil.getSpringPropertyDescriptor;
import static com.feilong.core.bean.PropertyDescriptorUtil.isUseSpringOperate;
import static com.feilong.core.util.CollectionsUtil.first;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.Collection;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.feilong.core.DefaultRuntimeException;
import com.feilong.core.Validate;
import com.feilong.core.lang.StringUtil;
import com.feilong.lib.beanutils.PropertyUtils;

/**
 * 属性值获取器.
 *
 * @author feilong
 * @since 1.12.0
 */
public final class PropertyValueObtainer{

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

    /** Don't let anyone instantiate this class. */
    private PropertyValueObtainer(){
        //AssertionError不是必须的. 但它可以避免不小心在类的内部调用构造器. 保证该类在任何情况下都不会被实例化.
        //see 《Effective Java》 2nd
        throw new AssertionError("No " + getClass().getName() + " instances for you!");
    }

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

    /**
     * Gets the property focus.
     *
     * @param 
     *            the generic type
     * @param bean
     *            the bean
     * @param propertyName
     *            the property name
     * @return the property focus
     */
    static  T obtain(Object bean,String propertyName){
        if (PropertyDescriptorUtil.isUseSpringOperate(bean.getClass(), propertyName)){
            return getDataUseSpring(bean, propertyName);
        }
        return getDataUseApache(bean, propertyName);
    }

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

    /**
     * Gets the data use apache.
     *
     * @param 
     *            the generic type
     * @param bean
     *            the bean
     * @param propertyName
     *            the property name
     * @return the data use apache
     */
    @SuppressWarnings("unchecked")
    private static  T getDataUseApache(Object bean,String propertyName){
        try{
            return (T) PropertyUtils.getProperty(bean, propertyName);
        }catch (Exception e){
            String pattern = "getProperty exception,bean:[{}],propertyName:[{}]";
            throw new BeanOperationException(StringUtil.formatPattern(pattern, bean, propertyName), e);
        }
    }

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

    /**
     * Gets the data use spring.
     *
     * @param 
     *            the generic type
     * @param bean
     *            the bean
     * @param propertyName
     *            the property name
     * @return the data use spring
     */
    private static  T getDataUseSpring(Object bean,String propertyName){
        LOGGER.trace("will use spring beanutils to execute:[{}],propertyName:[{}]", bean, propertyName);
        try{
            PropertyDescriptor propertyDescriptor = PropertyDescriptorUtil.getSpringPropertyDescriptor(bean.getClass(), propertyName);
            return getValue(bean, propertyDescriptor);
        }catch (Exception e){
            String pattern = "getProperty exception,bean:[{}],propertyName:[{}]";
            throw new BeanOperationException(StringUtil.formatPattern(pattern, bean, propertyName), e);
        }
    }

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

    /**
     * 循环beanIterable,调用 {@link PropertyUtil#getProperty(Object, String)} 获得 propertyName的值,塞到 returnCollection
     * 中返回.
     *
     * @param 
     *            the generic type
     * @param 
     *            the generic type
     * @param 
     *            the key type
     * @param beanIterable
     *            支持
     * 
     *            
    *
  • bean Iterable,比如List{@code },Set{@code }等
  • *
  • map Iterable,比如{@code List>}
  • *
  • list Iterable , 比如 {@code List>}
  • *
  • 数组 Iterable ,比如 {@code List}
  • *
* @param propertyName * 泛型O对象指定的属性名称,Possibly indexed and/or nested name of the property to be modified,参见 * propertyName * @param returnCollection * the return collection * @return 如果 returnCollection 是null,抛出 {@link NullPointerException}
* 如果 beanIterable 是null或者empty,返回 returnCollection
* 如果 propertyName 是null,抛出 {@link NullPointerException}
* 如果 propertyName 是blank,抛出 {@link IllegalArgumentException}
* @see PropertyUtil#getProperty(Object, String) * @see "org.apache.commons.beanutils.BeanToPropertyValueTransformer" * @since 1.0.8 */ public static > K getPropertyValueCollection( Iterable beanIterable, String propertyName, K returnCollection){ return getPropertyValueCollection(beanIterable, propertyName, returnCollection, null); } /** * 循环beanIterable,调用 {@link PropertyUtil#getProperty(Object, String)} 获得 propertyName的值,将值进行类型转换成 * returnElementClass ,塞到 returnCollection 中返回. * * @param * the generic type * @param * the generic type * @param * the key type * @param beanIterable * 支持 * *
    *
  • bean Iterable,比如List{@code },Set{@code }等
  • *
  • map Iterable,比如{@code List>}
  • *
  • list Iterable , 比如 {@code List>}
  • *
  • 数组 Iterable ,比如 {@code List}
  • *
* @param propertyName * 泛型O对象指定的属性名称,Possibly indexed and/or nested name of the property to be modified,参见 * propertyName * @param returnCollection * the return collection * @param returnElementClass * 如果 returnElementClass 是null,表示不需要类型转换 * @return 如果 returnCollection 是null,抛出 {@link NullPointerException}
* 如果 beanIterable 是null或者empty,返回 returnCollection
* 如果 propertyName 是null,抛出 {@link NullPointerException}
* 如果 propertyName 是blank,抛出 {@link IllegalArgumentException}
* 如果 returnElementClass 是null,表示不需要类型转换
* @see PropertyUtil#getProperty(Object, String) * @see "org.apache.commons.beanutils.BeanToPropertyValueTransformer" * @since 3.3.1 */ public static > K getPropertyValueCollection( Iterable beanIterable, String propertyName, K returnCollection, Class returnElementClass){ Validate.notBlank(propertyName, "propertyName can't be null/empty!"); //--------------------------------------------------------------- O o = first(beanIterable); Class klass = o.getClass(); //spring 操作 if (isUseSpringOperate(klass, propertyName)){ PropertyDescriptor propertyDescriptor = getSpringPropertyDescriptor(klass, propertyName); for (O bean : beanIterable){ returnCollection.add( convertValue(PropertyValueObtainer. getValue(bean, propertyDescriptor), returnElementClass)); } return returnCollection; } //--------------------------------------------------------------- for (O bean : beanIterable){ returnCollection.add(convertValue(PropertyUtil. getProperty(bean, propertyName), returnElementClass)); } return returnCollection; } //--------------------------------------------------------------- /** * 将 value 转成returnElementClass 类型. * * @param * the generic type * @param value * the value * @param returnElementClass * the return element class * @return 如果 returnElementClass 是null,表示不需要转换,直接返回 value
* @since 3.3.1 */ @SuppressWarnings("unchecked") private static T convertValue(Object value,Class returnElementClass){ if (null == returnElementClass){ return (T) value; } return convert(value, returnElementClass); } /** * Gets the value. * * @param * the generic type * @param * the generic type * @param obj * the obj * @param propertyDescriptor * the property descriptor * @return 如果 obj 是null,抛出 {@link NullPointerException}
* 如果 propertyDescriptor 是null,抛出 {@link NullPointerException}
* @see PropertyUtil.getProperty(Object, String) 排序异常 */ @SuppressWarnings("unchecked") public static T getValue(O obj,PropertyDescriptor propertyDescriptor){ Validate.notNull(obj, "obj can't be null!"); Validate.notNull(propertyDescriptor, "propertyDescriptor can't be null!"); //--------------------------------------------------------------- Method readMethod = propertyDescriptor.getReadMethod(); //--------------------------------------------------------------- //since 1.12.2 Validate.notNull( readMethod, "class:[%s],propertyDescriptor name:[%s],has no ReadMethod!!,pls check", obj.getClass().getCanonicalName(), propertyDescriptor.getDisplayName()); //--------------------------------------------------------------- //since 1.12.1 //https://github.com/venusdrogon/feilong-core/issues/760 readMethod = com.feilong.lib.beanutils.MethodUtils.getAccessibleMethod(obj.getClass(), readMethod); try{ return (T) readMethod.invoke(obj); }catch (ReflectiveOperationException e){ throw new DefaultRuntimeException(e); } } }