BeanToPropertyValueTransformer和commons-collections4

时间:2015-07-01 10:01:51

标签: java apache-commons-beanutils apache-commons-collection

commons-collections 3.2.1中,以下单行内容可以很好地检索myProperty中对象的myCollection值:

Collection<MyType> myTypes = (Collection<MyType>) CollectionUtils.collect(myCollection, new BeanToPropertyValueTransformer("myProperty"))

唯一的缺点是不支持泛型,因此需要进行类型转换。

什么是在commons-collection4中有效的解决方案,利用泛型?

2 个答案:

答案 0 :(得分:1)

显然,他们从BeanToPropertyValueTransformer版本中删除了apache-commons-collection4

我设法通过定义自定义Transformer来实现相同的行为。泛型的引入消除了输出集合的必要性:

Collection<MyInputType> myCollection = ...
Collection<MyType> myTypes = CollectionUtils.collect(myCollection, new Transformer<MyInputType, MyType>() {
    @Override
    public MyType transform(MyInputType input) {
        return input.getMyProperty();
    }
}

您也可以编写自己使用反射的Transformer

class ReflectionTransformer<O>
        implements
        Transformer<Object, O> {

    private String  reflectionString;

    public ReflectionTransformer(String reflectionString) {
        this.reflectionString = reflectionString;
    }

    @SuppressWarnings("unchecked")
    @Override
    public O transform(
            Object input) {
        try {
            return (O) BeanUtils.getProperty(input, reflectionString);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
    }
}

并使用它与您之前使用的BeanToPropertyValueTransformer

相同
Collection<MyType> myTypes = CollectionUtils.collect(myCollection, new ReflectionTransformer<MyType>("myProperty"));

答案 1 :(得分:0)

尝试使用以下类(使用 commons-collection4) -

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.lang.reflect.InvocationTargetException;

public class BeanToPropertyValueTransformer implements Transformer {

    private final Log log = LogFactory.getLog(this.getClass());

    private String propertyName;
    private boolean ignoreNull;
    
    public BeanToPropertyValueTransformer(final String propertyName) {
        this(propertyName, false);
    }

    public BeanToPropertyValueTransformer(final String propertyName, final boolean ignoreNull) {
        super();

        if ((propertyName != null) && (propertyName.length() > 0)) {
            this.propertyName = propertyName;
            this.ignoreNull = ignoreNull;
        } else {
            throw new IllegalArgumentException(
                "propertyName cannot be null or empty");
        }
    }
    
    public Object transform(final Object object) {

        Object propertyValue = null;

        try {
            propertyValue = PropertyUtils.getProperty(object, propertyName);
        } catch (final IllegalArgumentException e) {
            final String errorMsg = "Problem during transformation. Null value encountered in property path...";

            if (ignoreNull) {
                log.warn("WARNING: " + errorMsg + e);
            } else {
                final IllegalArgumentException iae = new IllegalArgumentException(errorMsg);
                if (!BeanUtils.initCause(iae, e)) {
                    log.error(errorMsg, e);
                }
                throw iae;
            }
        } catch (final IllegalAccessException e) {
            final String errorMsg = "Unable to access the property provided.";
            final IllegalArgumentException iae = new IllegalArgumentException(errorMsg);
            if (!BeanUtils.initCause(iae, e)) {
                log.error(errorMsg, e);
            }
            throw iae;
        } catch (final InvocationTargetException e) {
            final String errorMsg = "Exception occurred in property's getter";
            final IllegalArgumentException iae = new IllegalArgumentException(errorMsg);
            if (!BeanUtils.initCause(iae, e)) {
                log.error(errorMsg, e);
            }
            throw iae;
        } catch (final NoSuchMethodException e) {
            final String errorMsg = "No property found for name [" +
                propertyName + "]";
            final IllegalArgumentException iae = new IllegalArgumentException(errorMsg);
            if (!BeanUtils.initCause(iae, e)) {
                log.error(errorMsg, e);
            }
            throw iae;
        }

        return propertyValue;
    }

    public String getPropertyName() {
        return propertyName;
    }

    public boolean isIgnoreNull() {
        return ignoreNull;
    }
}