⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 beanutil.java

📁 Jodd是一个开源的公用Java基础类库
💻 JAVA
字号:
package jodd.bean;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import jodd.util.ReflectUtil;

/**
 * Miscellaneous and useful bean utilities.
 */
public class BeanUtil {

	// ---------------------------------------------------------------- misc

	private final static String GET_PREFIX = "get";
	private final static String SET_PREFIX = "set";
	private final static String IS_PREFIX = "is";

	private static String name2setter(String name) {
		return name2xxx(name, SET_PREFIX);
	}

	private static String name2getter(String name) {
		return name2xxx(name, GET_PREFIX);
	}

	private static String name2ister(String name) {
		return name2xxx(name, IS_PREFIX);
	}
	
	/**
	 * Formats the name of a property methods: it adds a prefix and capitalizes
	 * the first letter of property name.
	 *
	 * @param name   name of the property
	 * @param prefix get or set
	 *
	 * @return name of the property method (i.e. getXXX() or setXXX())
	 */
	private static String name2xxx(String name, String prefix) {
		if (name.startsWith(prefix) == true) {
			return name;
		}
		name = prefix + name.substring(0, 1).toUpperCase() + name.substring(1);
		return name;
	}


	// ---------------------------------------------------------------- set

	/**
	 * Sets JavaBean property. It finds setXxx() method (i.e. property) and
	 * inspects type of its (one and only) parameter. A converter object is
	 * called according to this type, value (as Object) is sent to Converter and
	 * the result is used for invoking setXxx() method. If a Converter can not be
	 * found, object is sended as it is.
	 * <p>
	 *
	 * Nested names are accepted and are separated by dot ('.').
	 *
	 * Note: there must *not* be more than one setXxx() with the same name.
	 * This is ok, since Java doesn't allow more than one getXxx() with
	 * the same name.
	 * <p>
	 *
	 * This method is much faster then one from Commons.
	 * <p>
	 *
	 * Method doesn't throw any exception.
	 *
	 * @param bean   java bean
	 * @param name   name of the property (not method, i.e. without "set" prefix)
	 * @param value  new value for the property
	 *
	 * @return <code>true</code> if setting succeed, <code>false</code> otherwise
	 */
	public static boolean setProperty(Object bean, String name, Object value) {
		if (bean == null) {
			return false;					// no objects
		}
		try {
			int dotNdx;
			while ( (dotNdx = name.indexOf('.')) != -1) {
				String methodName = name.substring(0, dotNdx);
				name = name.substring(dotNdx + 1);
				Method m = bean.getClass().getMethod(name2getter(methodName), null);
				bean = m.invoke(bean, null);
			}
		} catch (Exception ex) {
			return false;
		}
		Method m = ReflectUtil.getMethod(bean, name2setter(name));
		return setProperty(bean, m, value);
	}

	/**
	 * Internal set method.
	 */
	private static boolean setProperty(Object bean, Method m, Object value) {
		if (m == null) {
			return false;					// no setXXX() method
		}
		Class[] pts = m.getParameterTypes();
		if (pts.length != 1) {
			return false;					// setXXX() method doesn't have one parameter
		}
		Class parameter = pts[0];
		Converter objconv = ConvertersManager.get(parameter);
		try {
			if (objconv != null) {
				m.invoke(bean, new Object[] { objconv.convert(value) });
			} else {
				m.invoke(bean, new Object[] { value });
			}
			return true;
		} catch (IllegalArgumentException iaex) {
			return false;		// conversion failed
		} catch (Exception e) {
			return false;
		}
	}

	/**
	 * Sets all bean properties that are defined in the map for faster work.
	 *
	 * @param bean   java bean which properties has to be set
	 * @param map    map to read from
	 *
	 * @see #setProperty
	 * @see #getAllProperties
	 */
	public static void setAllProperties(Object bean, Map map) {
		Method[] ms = bean.getClass().getMethods();
		for (int i = 0; i < ms.length; i++) {
			String name = ms[i].getName();
			if (name.startsWith(SET_PREFIX)) {
				String pname = name.substring(3);
				if (map.containsKey(pname)) {
					Object value = map.get(pname);
					setProperty(bean, ms[i], value);
				}
			}
		}
		return;
	}


	// ---------------------------------------------------------------- get

	/**
	 * Gets the value from the bean parameter. If parameter doesn't exist in the
	 * bean, <code>null</code> is returned. Property name should be specified
	 * without 'get' prefix. Nested beans are allowed, separated by a dot ('.').
	 * If getXxx() method is not found, isXxx() method will be called.
	 * <p>
	 *
	 * Method doesn't throw any exception.
	 *
	 * @param bean   java bean
	 * @param name   property name
	 *
	 * @return null if parameter doesn't exist, otherwise parameters value.
	 */
	public static Object getProperty(Object bean, String name) {
		Object result = null;
		if (name == null) {
			return null;
		}
		try {
			int dotNdx;
			while ( (dotNdx = name.indexOf('.')) != -1) {
				String methodName = name.substring(0, dotNdx);
				name = name.substring(dotNdx + 1);
				Method m = bean.getClass().getMethod(name2getter(methodName), null);
				bean = m.invoke(bean, null);
			}

			Method m = null;
			Class beanClass = bean.getClass();
			try {
				m = beanClass.getMethod(name2getter(name), null);
			} catch (NoSuchMethodException nsmex) {
				m = beanClass.getMethod(name2ister(name), null);
			}
			result = m.invoke(bean, null);
		} catch (Exception ex) {
		}
		return result;
	}

	/**
	 * Returns all bean properties (getXxx()) as a <code>Map</code> for easier
	 * and faster manipulation. Property names (without 'get') are keys and
	 * property values are map values.
	 *
	 * @param bean   java bean which properties to read
	 *
	 * @return <code>Map</code> that contains all bean properties values
	 * @see #getProperty
	 * @see #setAllProperties
	 */
	public static Map getAllProperties(Object bean) {
		HashMap data = new HashMap();
		try {
			Method[] ms = bean.getClass().getMethods();
			for (int i = 0; i < ms.length; i++) {
				String name = ms[i].getName();
				if (name.startsWith(GET_PREFIX)) {
					String pname = name.substring(3);
					data.put(pname,	ms[i].invoke(bean, null));
				}
			}
		} catch (Exception ex){
		}
		return data;
	}

	// ---------------------------------------------------------------- copy properties


	/**
	 * Copies properties of one bean to another. It itterates all getXXX methods,
	 * reads values and populates another bean with setXXX.
	 *
	 * @param source source bean, one to read properties from
	 * @param destination
	 *               destination bean, to write properties to
	 */
	public static void copyProperties(Object source, Object destination) {
		if ((source == null) || (destination == null)) {
			return;
		}
		Method[] ms = source.getClass().getMethods();
		for (int i = 0; i < ms.length; i++) {
			String name = ms[i].getName();
			if (name.startsWith(GET_PREFIX)) {
				String propertyName = name.substring(3);
				Object value = getProperty(source, propertyName);
				setProperty(destination, propertyName, value);
			}
		}
	}


	// ---------------------------------------------------------------- forEach

	/**
	 * Iterrates all read properties and executes callback method on it
	 *
	 * @param bean   bean that will be modified
	 * @param fepcb  modifier that will be called back for properties modifications
	 */
	public static void forEachProperty(Object bean, PropertyCallback fepcb) {
		Method[] ms = bean.getClass().getMethods();
		for (int i = 0; i < ms.length; i++) {
			String name = ms[i].getName();
			if (name.startsWith(GET_PREFIX)) {
				fepcb.onProperty(bean, name.substring(3));
			}
		}
	}


	// ---------------------------------------------------------------- load

	/**
	 * Populates bean from given object by using a loader for given objects type.
	 * Only read-write properties can be loaded.
	 *
	 * @param bean   java bean
	 * @param obj    object
	 */
	public static void load(Object bean, Object obj) {
		Loader load = LoadersManager.get(obj);
		if (load == null) {
			return;
		}
		load.load(bean, obj);
	}

	// ---------------------------------------------------------------- toString

	/**
	 * Creates formated string that contains names of all readable properties
	 * (getXXX() methods) and their values. For debugging purposes only.
	 *
	 * @param o      java bean
	 *
	 * @return formated String that contains info about all beans properties.
	 */
	public static String toString(Object o) {
		StringBuffer result = new StringBuffer("Bean: ");
		if (o == null) {
			result.append("null");
			return result.toString();
		}
		result.append(o.getClass().getName()).append("\n");
		
		Method[] ms = o.getClass().getMethods();
		for (int i = 0; i < ms.length; i++) {
			Method m = ms[i];
			Class[] params = m.getParameterTypes();
			if (params.length != 0) {
				continue;								// skip methods that have params
			}
			String mname = m.getName();
			if (mname.equals("getClass")) {				// skip getClass() method
				continue;
			}
			if (mname.startsWith(GET_PREFIX)) {			// getXXX() method found
				String paramName = m.getName().substring(3);
				Object mresult = null;
				try {
					mresult = m.invoke(o, null);
				} catch (Exception ex) {
				}
				result.append("  ").append(paramName);
				if (mresult != null) {
					result.append(":[").append(mresult.toString()).append("]");
				} else {
					result.append(":null");
				}
				result.append("\n");
					
			}
		}
		return result.toString();
	}


}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -