📄 beanutil.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 + -