📄 beanutils.java
字号:
public static Method findMethodWithMinimalParameters(Class clazz, String methodName) {
Method[] methods = clazz.getMethods();
Method targetMethod = null;
for (int i = 0; i < methods.length; i++) {
if (methods[i].getName().equals(methodName)) {
if (targetMethod == null ||
methods[i].getParameterTypes().length < targetMethod.getParameterTypes().length) {
targetMethod = methods[i];
}
}
}
if (targetMethod != null) {
return targetMethod;
}
else {
return findDeclaredMethodWithMinimalParameters(clazz, methodName);
}
}
/**
* Find a method with the given method name and minimal parameters (best case: none),
* declared on the given class or one of its superclasses. Will return a public,
* protected, package access, or private method.
* <p>Checks <code>Class.getDeclaredMethods</code>, cascading upwards to all superclasses.
* @param clazz the class to check
* @param methodName the name of the method to find
* @return the method object, or <code>null</code> if not found
* @see java.lang.Class#getDeclaredMethods
*/
public static Method findDeclaredMethodWithMinimalParameters(Class clazz, String methodName) {
Method[] methods = clazz.getDeclaredMethods();
Method targetMethod = null;
for (int i = 0; i < methods.length; i++) {
if (methods[i].getName().equals(methodName)) {
if (targetMethod == null ||
methods[i].getParameterTypes().length < targetMethod.getParameterTypes().length) {
targetMethod = methods[i];
}
}
}
if (targetMethod != null) {
return targetMethod;
}
else {
if (clazz.getSuperclass() != null) {
return findDeclaredMethodWithMinimalParameters(clazz.getSuperclass(), methodName);
}
return null;
}
}
/**
* Retrieve the JavaBeans <code>PropertyDescriptor</code>s of a given class.
* @param clazz the Class to retrieve the PropertyDescriptors for
* @return an array of <code>PropertyDescriptors</code> for the given class
* @throws BeansException if PropertyDescriptor look fails
*/
public static PropertyDescriptor[] getPropertyDescriptors(Class clazz) throws BeansException {
CachedIntrospectionResults cr = CachedIntrospectionResults.forClass(clazz);
return cr.getBeanInfo().getPropertyDescriptors();
}
/**
* Retrieve the JavaBeans <code>PropertyDescriptors</code> for the given property.
* @param clazz the Class to retrieve the PropertyDescriptor for
* @param propertyName the name of the property
* @return the corresponding PropertyDescriptor, or <code>null</code> if none
* @throws BeansException if PropertyDescriptor lookup fails
*/
public static PropertyDescriptor getPropertyDescriptor(Class clazz, String propertyName)
throws BeansException {
CachedIntrospectionResults cr = CachedIntrospectionResults.forClass(clazz);
return cr.getPropertyDescriptor(propertyName);
}
/**
* Find a JavaBeans <code>PropertyDescriptor</code> for the given method,
* with the method either being the read method or the write method for
* that bean property.
* @param method the method to find a corresponding PropertyDescriptor for
* @return the corresponding PropertyDescriptor, or <code>null</code> if none
* @throws BeansException if PropertyDescriptor lookup fails
*/
public static PropertyDescriptor findPropertyForMethod(Method method) throws BeansException {
Assert.notNull(method, "method must not be null");
PropertyDescriptor[] pds = getPropertyDescriptors(method.getDeclaringClass());
for (int i = 0; i < pds.length; i++) {
if (method.equals(pds[i].getReadMethod()) || method.equals(pds[i].getWriteMethod())) {
return pds[i];
}
}
return null;
}
/**
* Determine the canonical name for the given property path.
* Removes surrounding quotes from map keys:<br>
* <code>map['key']</code> -> <code>map[key]</code><br>
* <code>map["key"]</code> -> <code>map[key]</code>
* @param propertyName the bean property path
* @return the canonical representation of the property path
*/
public static String canonicalName(String propertyName) {
if (propertyName == null) {
return "";
}
// The following code does not use JDK 1.4's StringBuffer.indexOf(String)
// method to retain JDK 1.3 compatibility. The slight loss in performance
// is not really relevant, as this code will typically just run on startup.
StringBuffer buf = new StringBuffer(propertyName);
int searchIndex = 0;
while (searchIndex != -1) {
int keyStart = buf.toString().indexOf(PropertyAccessor.PROPERTY_KEY_PREFIX, searchIndex);
searchIndex = -1;
if (keyStart != -1) {
int keyEnd = buf.toString().indexOf(
PropertyAccessor.PROPERTY_KEY_SUFFIX, keyStart + PropertyAccessor.PROPERTY_KEY_PREFIX.length());
if (keyEnd != -1) {
String key = buf.substring(keyStart + PropertyAccessor.PROPERTY_KEY_PREFIX.length(), keyEnd);
if ((key.startsWith("'") && key.endsWith("'")) || (key.startsWith("\"") && key.endsWith("\""))) {
buf.delete(keyStart + 1, keyStart + 2);
buf.delete(keyEnd - 2, keyEnd - 1);
keyEnd = keyEnd - 2;
}
searchIndex = keyEnd + PropertyAccessor.PROPERTY_KEY_SUFFIX.length();
}
}
}
return buf.toString();
}
/**
* Copy the property values of the given source bean into the target bean.
* <p>Note: The source and target classes do not have to match or even be derived
* from each other, as long as the properties match. Any bean properties that the
* source bean exposes but the target bean does not will silently be ignored.
* <p>This is just a convenience method. For more complex transfer needs,
* consider using a full BeanWrapper.
* @param source the source bean
* @param target the target bean
* @throws BeansException if the copying failed
* @see BeanWrapper
*/
public static void copyProperties(Object source, Object target) throws BeansException {
copyProperties(source, target, null, null);
}
/**
* Copy the property values of the given source bean into the given target bean,
* only setting properties defined in the given "editable" class (or interface).
* <p>Note: The source and target classes do not have to match or even be derived
* from each other, as long as the properties match. Any bean properties that the
* source bean exposes but the target bean does not will silently be ignored.
* <p>This is just a convenience method. For more complex transfer needs,
* consider using a full BeanWrapper.
* @param source the source bean
* @param target the target bean
* @param editable the class (or interface) to restrict property setting to
* @throws BeansException if the copying failed
* @see BeanWrapper
*/
public static void copyProperties(Object source, Object target, Class editable)
throws BeansException {
copyProperties(source, target, editable, null);
}
/**
* Copy the property values of the given source bean into the given target bean,
* ignoring the given "ignoreProperties".
* <p>Note: The source and target classes do not have to match or even be derived
* from each other, as long as the properties match. Any bean properties that the
* source bean exposes but the target bean does not will silently be ignored.
* <p>This is just a convenience method. For more complex transfer needs,
* consider using a full BeanWrapper.
* @param source the source bean
* @param target the target bean
* @param ignoreProperties array of property names to ignore
* @throws BeansException if the copying failed
* @see BeanWrapper
*/
public static void copyProperties(Object source, Object target, String[] ignoreProperties)
throws BeansException {
copyProperties(source, target, null, ignoreProperties);
}
/**
* Copy the property values of the given source bean into the given target bean.
* <p>Note: The source and target classes do not have to match or even be derived
* from each other, as long as the properties match. Any bean properties that the
* source bean exposes but the target bean does not will silently be ignored.
* @param source the source bean
* @param target the target bean
* @param editable the class (or interface) to restrict property setting to
* @param ignoreProperties array of property names to ignore
* @throws BeansException if the copying failed
* @see BeanWrapper
*/
private static void copyProperties(Object source, Object target, Class editable, String[] ignoreProperties)
throws BeansException {
Assert.notNull(source, "source must not be null");
Assert.notNull(target, "target must not be null");
Class actualEditable = target.getClass();
if (editable != null) {
if (!editable.isInstance(target)) {
throw new IllegalArgumentException("Target class [" + target.getClass().getName() +
"] not assignable to Editable class [" + editable.getName() + "]");
}
actualEditable = editable;
}
PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
List ignoreList = (ignoreProperties != null) ? Arrays.asList(ignoreProperties) : null;
for (int i = 0; i < targetPds.length; i++) {
PropertyDescriptor targetPd = targetPds[i];
if (targetPd.getWriteMethod() != null &&
(ignoreProperties == null || (!ignoreList.contains(targetPd.getName())))) {
PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
if (sourcePd != null && sourcePd.getReadMethod() != null) {
try {
Method readMethod = sourcePd.getReadMethod();
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
readMethod.setAccessible(true);
}
Object value = readMethod.invoke(source, new Object[0]);
Method writeMethod = targetPd.getWriteMethod();
if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
writeMethod.setAccessible(true);
}
writeMethod.invoke(target, new Object[] {value});
}
catch (Exception ex) {
throw new FatalBeanException("Could not copy properties from source to target", ex);
}
}
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -