package com.songbx;
import java.beans.Introspector;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import org.hibernate.HibernateException;
import org.hibernate.PropertyAccessException;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.property.Getter;
import org.hibernate.property.Setter;
import org.hibernate.util.ReflectHelper;
public class BasicPropertyAccessor {
public static final class BasicSetter implements Setter {
private Class clazz;
private final transient Method method;
private final String propertyName;
private BasicSetter(Class clazz, Method method, String propertyName) {
this.clazz=clazz;
this.method=method;
this.propertyName=propertyName;
}
public void set(Object target, Object value, SessionFactoryImplementor factory)
throws HibernateException {
try {
method.invoke( target, new Object[] { value } );
}
catch (NullPointerException npe) {
if ( value==null && method.getParameterTypes()[0].isPrimitive() ) {//判定指定的 Class 对象是否表示一个基本类型。
throw new PropertyAccessException(
npe,
"Null value was assigned to a property of primitive type",
true,
clazz,
propertyName
);
}
else {
throw new PropertyAccessException(
npe,
"NullPointerException occurred while calling",
true,
clazz,
propertyName
);
}
}
catch (InvocationTargetException ite) {
throw new PropertyAccessException(
ite,
"Exception occurred inside",
true,
clazz,
propertyName
);
}
catch (IllegalAccessException iae) {
throw new PropertyAccessException(
iae,
"IllegalAccessException occurred while calling",
true,
clazz,
propertyName
);
//cannot occur
}
catch (IllegalArgumentException iae) {
if ( value==null && method.getParameterTypes()[0].isPrimitive() ) {
throw new PropertyAccessException(
iae,
"Null value was assigned to a property of primitive type",
true,
clazz,
propertyName
);
}
else {
throw new PropertyAccessException(
iae,
"IllegalArgumentException occurred while calling",
true,
clazz,
propertyName
);
}
}
}
public Method getMethod() {
return method;
}
public String getMethodName() {
return method.getName();
}
public String toString() {
return "BasicSetter(" + clazz.getName() + '.' + propertyName + ')';
}
}
public static final class BasicGetter implements Getter {
private Class clazz;
private final transient Method method;
private final String propertyName;
private BasicGetter(Class clazz, Method method, String propertyName) {
this.clazz=clazz;
this.method=method;
this.propertyName=propertyName;
}
public Object get(Object target) throws HibernateException {
try {
return method.invoke(target, null);
}
catch (InvocationTargetException ite) {
throw new PropertyAccessException(
ite,
"Exception occurred inside",
false,
clazz,
propertyName
);
}
catch (IllegalAccessException iae) {
throw new PropertyAccessException(
iae,
"IllegalAccessException occurred while calling",
false,
clazz,
propertyName
);
//cannot occur
}
catch (IllegalArgumentException iae) {
throw new PropertyAccessException(
iae,
"IllegalArgumentException occurred calling",
false,
clazz,
propertyName
);
}
}
public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) {
return get( target );
}
public Class getReturnType() {
return method.getReturnType();
}
public Method getMethod() {
return method;
}
public String getMethodName() {
return method.getName();
}
public String toString() {
return "BasicGetter(" + clazz.getName() + '.' + propertyName + ')';
}
}
private static BasicSetter getSetterOrNull(Class theClass, String propertyName) {
if (theClass==Object.class || theClass==null) return null;
Method method = setterMethod(theClass, propertyName);
if (method!=null) {
if ( !ReflectHelper.isPublic(theClass, method) ) method.setAccessible(true);
return new BasicSetter(theClass, method, propertyName);
}
else {
BasicSetter setter = getSetterOrNull( theClass.getSuperclass(), propertyName );
if (setter==null) {
Class[] interfaces = theClass.getInterfaces();
for ( int i=0; setter==null && i
setter=getSetterOrNull( interfaces[i], propertyName );
}
}
return setter;
}
}
private static Method setterMethod(Class theClass, String propertyName) {
BasicGetter getter = getGetterOrNull(theClass, propertyName);
Class returnType = (getter==null) ? null : getter.getReturnType();
Method[] methods = theClass.getDeclaredMethods();
Method potentialSetter = null;
for (int i=0; i
String methodName = methods[i].getName();
if ( methods[i].getParameterTypes().length==1 && methodName.startsWith("set") ) {
//获得一个字符串并将它转换成普通 Java 可用名称大写形式的实用程序方法。
String testStdMethod = Introspector.decapitalize( methodName.substring(3) );
String testOldMethod = methodName.substring(3);
if ( testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName) ) {
potentialSetter = methods[i];
if ( returnType==null || methods[i].getParameterTypes()[0].equals(returnType) ) {
return potentialSetter;
}
}
}
}
return potentialSetter;
}
private static BasicGetter getGetterOrNull(Class theClass, String propertyName) {
if (theClass==Object.class || theClass==null) return null;
Method method = getterMethod(theClass, propertyName);
if (method!=null) {
if ( !ReflectHelper.isPublic(theClass, method) ) method.setAccessible(true);//将此对象的 accessible 标志设置为指示的布尔值
return new BasicGetter(theClass, method, propertyName);
}
else {
//检查父类的getter方法
BasicGetter getter = getGetterOrNull( theClass.getSuperclass(), propertyName );
if (getter==null) {
Class[] interfaces = theClass.getInterfaces();
for ( int i=0; getter==null && i
getter=getGetterOrNull( interfaces[i], propertyName );
}
}
return getter;
}
}
private static Method getterMethod(Class theClass, String propertyName) {
Method[] methods = theClass.getDeclaredMethods();// 返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
for (int i=0; i
// only carry on if the method has no parameters
if ( methods[i].getParameterTypes().length==0 ) {
String methodName = methods[i].getName();
// try "get"
if ( methodName.startsWith("get") ) {
String testStdMethod = Introspector.decapitalize( methodName.substring(3) );//获得一个字符串并将它转换成普通 Java 可用名称大写形式的实用程序方法。
String testOldMethod = methodName.substring(3);
if ( testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName) ) {
return methods[i];
}
}
// if not "get" then try "is"
/*boolean isBoolean = methods[i].getReturnType().equals(Boolean.class) ||
methods[i].getReturnType().equals(boolean.class);*/
if ( methodName.startsWith("is") ) {
String testStdMethod = Introspector.decapitalize( methodName.substring(2) );
String testOldMethod = methodName.substring(2);
if ( testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName) ) {
return methods[i];
}
}
}
}
return null;
}
}