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

org.mule.util.BeanUtils Maven / Gradle / Ivy

There is a newer version: 3.9.0
Show newest version
/*
 * $Id: BeanUtils.java 19191 2010-08-25 21:05:23Z tcarlson $
 * --------------------------------------------------------------------------------------
 * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 *
 * The software in this package is published under the terms of the CPAL v1.0
 * license, a copy of which has been included with this distribution in the
 * LICENSE.txt file.
 */

package org.mule.util;

import org.mule.config.i18n.CoreMessages;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * BeanUtils provides functions for altering the way commons BeanUtils
 * works
 */
// @ThreadSafe
public class BeanUtils extends org.apache.commons.beanutils.BeanUtils
{
    public static final String SET_PROPERTIES_METHOD = "setProperties";

    /**
     * logger used by this class
     */
    private static final Log logger = LogFactory.getLog(BeanUtils.class);

    /**
     * Exception safe version of BeanUtils.populate()
     *
     * @param object      the object to set the properties on
     * @param props       the map of properties to set
     * @param logWarnings whether exception warnings should be logged
     */
    public static void populateWithoutFail(Object object, Map props, boolean logWarnings)
    {
        // Check to see if our object has a setProperties method where the properties
        // map should be set
        if (ClassUtils.getMethod(object.getClass(), SET_PROPERTIES_METHOD, new Class[]{Map.class}) != null)
        {
            try
            {
                BeanUtils.setProperty(object, "properties", props);
            }
            catch (Exception e)
            {
                // this should never happen since we explicitly check for the method
                // above
                if (logWarnings)
                {
                    logger.warn("Property: " + SET_PROPERTIES_METHOD + "=" + Map.class.getName()
                            + " not found on object: " + object.getClass().getName());
                }
            }
        }
        else
        {
            for (Iterator iterator = props.entrySet().iterator(); iterator.hasNext();)
            {
                Map.Entry entry = (Map.Entry) iterator.next();

                try
                {
                    BeanUtils.setProperty(object, entry.getKey().toString(), entry.getValue());
                }
                catch (Exception e)
                {
                    if (logWarnings)
                    {
                        logger.warn("Property: " + entry.getKey() + "=" + entry.getValue()
                                + " not found on object: " + object.getClass().getName());
                    }
                }
            }
        }
    }

    /**
     * This will overlay a map of properties on a bean.  This method will validate that all properties are available
     * on the bean before setting the properties
     *
     * @param bean  the bean on which to set the properties
     * @param props a Map of properties to set on the bean
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    public static void populate(Object bean, Map props) throws IllegalAccessException, InvocationTargetException
    {
        // Check to see if our object has a setProperties method where the properties
        // map should be set
        if (ClassUtils.getMethod(bean.getClass(), SET_PROPERTIES_METHOD, new Class[]{Map.class}) != null)
        {
            BeanUtils.setProperty(bean, "properties", props);
        }
        else
        {
            Map master = describe(bean);
            for (Iterator iterator = props.keySet().iterator(); iterator.hasNext();)
            {
                Object o = iterator.next();
                if (!master.containsKey(o))
                {
                    throw new IllegalArgumentException(CoreMessages.propertyDoesNotExistOnObject(o.toString(), bean).getMessage());
                }

            }
            org.apache.commons.beanutils.BeanUtils.populate(bean, props);
        }
    }

    /**
     * The Apache BeanUtils version of this converts all values to String, which is pretty useless, it also includes
     * stuff not defined by the user
     *
     * @param object the object to Describe
     * @return a map of the properties on the object
     */
    public static Map describe(Object object)
    {
        Map props = new HashMap(object.getClass().getDeclaredFields().length);
        for (int i = 0; i < object.getClass().getDeclaredFields().length; i++)
        {
            Field field = object.getClass().getDeclaredFields()[i];
            field.setAccessible(true);
            try
            {
                props.put(field.getName(), field.get(object));
            }
            catch (IllegalAccessException e)
            {
                logger.debug("Unable to read field: " + field.getName() + " on object: " + object);
            }
        }
        return props;
    }

    /**
     * Similar to {@link #describe(Object)} except that it will only populate bean properties where there is a valid
     * getter and setter method. Basically this method will describe a bean and honour its encapsulation.
     *
     * @param object the object to describe
     * @return a map of published properties
     */
    public static Map describeBean(Object object)
    {
        Map props = new HashMap();
        for (int i = 0; i < object.getClass().getMethods().length; i++)
        {
            Method method = object.getClass().getMethods()[i];
            if (method.getName().startsWith("get") || method.getName().startsWith("is"))
            {
                String field = (method.getName().startsWith("is") ? method.getName().substring(2) : method.getName().substring(3));
                String setter = "set" + field;
                try
                {
                    object.getClass().getMethod(setter, method.getReturnType());
                }
                catch (NoSuchMethodException e)
                {
                    logger.debug("Ignoring bean property: " + e.getMessage());
                    continue;
                }
                field = field.substring(0, 1).toLowerCase() + field.substring(1);
                try
                {
                    props.put(field, method.invoke(object));
                }
                catch (Exception e)
                {
                    logger.debug("unable to call bean method: " + method);
                }
            }
        }
        return props;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy