gu.sql2java.bean.LenientDecoratorOfDescriptor Maven / Gradle / Ivy
package gu.sql2java.bean;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
/**
* 重写{@link #getWriteMethod()}方法,允许返回类型不为void的write方法
* @author guyadong
*
*/
public class LenientDecoratorOfDescriptor extends PropertyDescriptor {
private final PropertyDescriptor descriptor;
private LenientDecoratorOfDescriptor(PropertyDescriptor descriptor) throws IntrospectionException {
super(descriptor.getName(),
classOf(descriptor),
readMethodNameOf(descriptor),
writeMethodNameOf(descriptor));
this.descriptor = descriptor;
}
private static String readMethodNameOf(PropertyDescriptor descriptor){
Method m = descriptor.getReadMethod();
return null == m ? null : m.getName();
}
private static String writeMethodNameOf(PropertyDescriptor descriptor){
Method m = descriptor.getWriteMethod();
return null == m ? null : m.getName();
}
/**
* 反射方法调用{@code FeatureDescriptor.getClass0()} 方法
* @param descriptor
* @return class0 result
*/
private static Class> classOf(PropertyDescriptor descriptor){
try {
Method m = (Method) internalFindMethod(descriptor.getClass(),"getClass0");
m.setAccessible(true);
return (Class>) m.invoke(descriptor);
} catch (NullPointerException e) {
throw e;
}catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Returns a String which capitalizes the first letter of the string.
*/
private static String capitalize(String name) {
if (name == null || name.length() == 0) {
return name;
}
return name.substring(0, 1).toUpperCase() + name.substring(1);
}
@Override
public synchronized Method getWriteMethod() {
Method writeMethod = super.getWriteMethod();
if (writeMethod == null) {
// 先获取read方法,如果classRef为null,会用read方法所属的类初始化
Method readMethod = getReadMethod();
Class> cls = classOf(this);
if(cls != null){
String writeMethodName = "set" + capitalize(getName());
Class>readReturnType = null;
if(readMethod != null){
readReturnType = readMethod.getReturnType();
}
// 遍历所有方法查找指定名字的方法,
// 如果存在read方法,匹配只有一个参数且参数类型与读取方法的返回类型一致的方法
// 如果不存在read方法,匹配只有一个参数方法
for(Method method : cls.getMethods()){
Class>[] parameterTypes = method.getParameterTypes();
if(method.getName().equals(writeMethodName) && parameterTypes.length == 1){
try{
if(readReturnType != null){
// 如果有read方法,则参数类型必须与read方法返回值类型一致
if(parameterTypes[0].equals(readReturnType)){
setWriteMethod(method);
writeMethod = method;
break;
}
}else{
setWriteMethod(method);
writeMethod = method;
break;
}
} catch (IntrospectionException e) {
// fall through
}
}
}
}
}
return writeMethod;
}
public PropertyDescriptor origin() {
return descriptor;
}
public static LenientDecoratorOfDescriptor toDecorator(PropertyDescriptor descriptor){
if(descriptor == null){
return null;
}
if(descriptor instanceof LenientDecoratorOfDescriptor){
return (LenientDecoratorOfDescriptor)descriptor;
}
try {
return new LenientDecoratorOfDescriptor(descriptor);
} catch (IntrospectionException e) {
throw new RuntimeException(e);
}
}
/**
* Internal support for finding a target methodName with a given
* parameter list on a given class.
*/
private static Method internalFindMethod(Class> start, String methodName,Class> ...args) {
Method method = null;
for (Class> cl = start; cl != null && cl.getDeclaringClass() != Object.class && method == null; cl = cl.getSuperclass()) {
try {
method = cl.getDeclaredMethod(methodName, args);
} catch (NoSuchMethodException e) {
}
}
return method;
}
}