org.mule.util.BeanUtils Maven / Gradle / Ivy
/*
* $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