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<interfaces.length; 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<methods.length; 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<interfaces.length; 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<methods.length; 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; } } Class isInstance(Object obj) 判定指定的 Object 是否与此 Class 所表示的对象赋值兼容。