1 package org.hibernate.property; 3 4 import java.beans.Introspector ; 5 import java.lang.reflect.InvocationTargetException ; 6 import java.lang.reflect.Method ; 7 import java.util.Map ; 8 9 import org.apache.commons.logging.Log; 10 import org.apache.commons.logging.LogFactory; 11 12 import org.hibernate.HibernateException; 13 import org.hibernate.PropertyAccessException; 14 import org.hibernate.PropertyNotFoundException; 15 import org.hibernate.engine.SessionFactoryImplementor; 16 import org.hibernate.engine.SessionImplementor; 17 import org.hibernate.util.ReflectHelper; 18 19 24 public class BasicPropertyAccessor implements PropertyAccessor { 25 26 private static final Log log = LogFactory.getLog(BasicPropertyAccessor.class); 27 28 public static final class BasicSetter implements Setter { 29 private Class clazz; 30 private final transient Method method; 31 private final String propertyName; 32 33 private BasicSetter(Class clazz, Method method, String propertyName) { 34 this.clazz=clazz; 35 this.method=method; 36 this.propertyName=propertyName; 37 } 38 39 public void set(Object target, Object value, SessionFactoryImplementor factory) 40 throws HibernateException { 41 try { 42 method.invoke( target, new Object [] { value } ); 43 } 44 catch (NullPointerException npe) { 45 if ( value==null && method.getParameterTypes()[0].isPrimitive() ) { 46 throw new PropertyAccessException( 47 npe, 48 "Null value was assigned to a property of primitive type", 49 true, 50 clazz, 51 propertyName 52 ); 53 } 54 else { 55 throw new PropertyAccessException( 56 npe, 57 "NullPointerException occurred while calling", 58 true, 59 clazz, 60 propertyName 61 ); 62 } 63 } 64 catch (InvocationTargetException ite) { 65 throw new PropertyAccessException( 66 ite, 67 "Exception occurred inside", 68 true, 69 clazz, 70 propertyName 71 ); 72 } 73 catch (IllegalAccessException iae) { 74 throw new PropertyAccessException( 75 iae, 76 "IllegalAccessException occurred while calling", 77 true, 78 clazz, 79 propertyName 80 ); 81 } 83 catch (IllegalArgumentException iae) { 84 if ( value==null && method.getParameterTypes()[0].isPrimitive() ) { 85 throw new PropertyAccessException( 86 iae, 87 "Null value was assigned to a property of primitive type", 88 true, 89 clazz, 90 propertyName 91 ); 92 } 93 else { 94 log.error( 95 "IllegalArgumentException in class: " + clazz.getName() + 96 ", setter method of property: " + propertyName 97 ); 98 log.error( 99 "expected type: " + 100 method.getParameterTypes()[0].getName() + 101 ", actual value: " + 102 ( value==null ? null : value.getClass().getName() ) 103 ); 104 throw new PropertyAccessException( 105 iae, 106 "IllegalArgumentException occurred while calling", 107 true, 108 clazz, 109 propertyName 110 ); 111 } 112 } 113 } 114 115 public Method getMethod() { 116 return method; 117 } 118 119 public String getMethodName() { 120 return method.getName(); 121 } 122 123 Object readResolve() { 124 return createSetter(clazz, propertyName); 125 } 126 127 public String toString() { 128 return "BasicSetter(" + clazz.getName() + '.' + propertyName + ')'; 129 } 130 } 131 132 public static final class BasicGetter implements Getter { 133 private Class clazz; 134 private final transient Method method; 135 private final String propertyName; 136 137 private BasicGetter(Class clazz, Method method, String propertyName) { 138 this.clazz=clazz; 139 this.method=method; 140 this.propertyName=propertyName; 141 } 142 143 public Object get(Object target) throws HibernateException { 144 try { 145 return method.invoke(target, null); 146 } 147 catch (InvocationTargetException ite) { 148 throw new PropertyAccessException( 149 ite, 150 "Exception occurred inside", 151 false, 152 clazz, 153 propertyName 154 ); 155 } 156 catch (IllegalAccessException iae) { 157 throw new PropertyAccessException( 158 iae, 159 "IllegalAccessException occurred while calling", 160 false, 161 clazz, 162 propertyName 163 ); 164 } 166 catch (IllegalArgumentException iae) { 167 log.error( 168 "IllegalArgumentException in class: " + clazz.getName() + 169 ", getter method of property: " + propertyName 170 ); 171 throw new PropertyAccessException( 172 iae, 173 "IllegalArgumentException occurred calling", 174 false, 175 clazz, 176 propertyName 177 ); 178 } 179 } 180 181 public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) { 182 return get( target ); 183 } 184 185 public Class getReturnType() { 186 return method.getReturnType(); 187 } 188 189 public Method getMethod() { 190 return method; 191 } 192 193 public String getMethodName() { 194 return method.getName(); 195 } 196 197 public String toString() { 198 return "BasicGetter(" + clazz.getName() + '.' + propertyName + ')'; 199 } 200 201 Object readResolve() { 202 return createGetter(clazz, propertyName); 203 } 204 } 205 206 207 public Setter getSetter(Class theClass, String propertyName) 208 throws PropertyNotFoundException { 209 return createSetter(theClass, propertyName); 210 } 211 212 private static Setter createSetter(Class theClass, String propertyName) 213 throws PropertyNotFoundException { 214 BasicSetter result = getSetterOrNull(theClass, propertyName); 215 if (result==null) { 216 throw new PropertyNotFoundException( 217 "Could not find a setter for property " + 218 propertyName + 219 " in class " + 220 theClass.getName() 221 ); 222 } 223 return result; 224 } 225 226 private static BasicSetter getSetterOrNull(Class theClass, String propertyName) { 227 228 if (theClass==Object .class || theClass==null) return null; 229 230 Method method = setterMethod(theClass, propertyName); 231 232 if (method!=null) { 233 if ( !ReflectHelper.isPublic(theClass, method) ) method.setAccessible(true); 234 return new BasicSetter(theClass, method, propertyName); 235 } 236 else { 237 BasicSetter setter = getSetterOrNull( theClass.getSuperclass(), propertyName ); 238 if (setter==null) { 239 Class [] interfaces = theClass.getInterfaces(); 240 for ( int i=0; setter==null && i<interfaces.length; i++ ) { 241 setter=getSetterOrNull( interfaces[i], propertyName ); 242 } 243 } 244 return setter; 245 } 246 247 } 248 249 private static Method setterMethod(Class theClass, String propertyName) { 250 251 BasicGetter getter = getGetterOrNull(theClass, propertyName); 252 Class returnType = (getter==null) ? null : getter.getReturnType(); 253 254 Method [] methods = theClass.getDeclaredMethods(); 255 Method potentialSetter = null; 256 for (int i=0; i<methods.length; i++) { 257 String methodName = methods[i].getName(); 258 259 if ( methods[i].getParameterTypes().length==1 && methodName.startsWith("set") ) { 260 String testStdMethod = Introspector.decapitalize( methodName.substring(3) ); 261 String testOldMethod = methodName.substring(3); 262 if ( testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName) ) { 263 potentialSetter = methods[i]; 264 if ( returnType==null || methods[i].getParameterTypes()[0].equals(returnType) ) { 265 return potentialSetter; 266 } 267 } 268 } 269 } 270 return potentialSetter; 271 } 272 273 public Getter getGetter(Class theClass, String propertyName) 274 throws PropertyNotFoundException { 275 return createGetter(theClass, propertyName); 276 } 277 278 public static Getter createGetter(Class theClass, String propertyName) 279 throws PropertyNotFoundException { 280 BasicGetter result = getGetterOrNull(theClass, propertyName); 281 if (result==null) { 282 throw new PropertyNotFoundException( 283 "Could not find a getter for " + 284 propertyName + 285 " in class " + 286 theClass.getName() 287 ); 288 } 289 return result; 290 291 } 292 293 private static BasicGetter getGetterOrNull(Class theClass, String propertyName) { 294 295 if (theClass==Object .class || theClass==null) return null; 296 297 Method method = getterMethod(theClass, propertyName); 298 299 if (method!=null) { 300 if ( !ReflectHelper.isPublic(theClass, method) ) method.setAccessible(true); 301 return new BasicGetter(theClass, method, propertyName); 302 } 303 else { 304 BasicGetter getter = getGetterOrNull( theClass.getSuperclass(), propertyName ); 305 if (getter==null) { 306 Class [] interfaces = theClass.getInterfaces(); 307 for ( int i=0; getter==null && i<interfaces.length; i++ ) { 308 getter=getGetterOrNull( interfaces[i], propertyName ); 309 } 310 } 311 return getter; 312 } 313 } 314 315 private static Method getterMethod(Class theClass, String propertyName) { 316 317 Method [] methods = theClass.getDeclaredMethods(); 318 for (int i=0; i<methods.length; i++) { 319 if ( methods[i].getParameterTypes().length==0 ) { 321 String methodName = methods[i].getName(); 322 323 if ( methodName.startsWith("get") ) { 325 String testStdMethod = Introspector.decapitalize( methodName.substring(3) ); 326 String testOldMethod = methodName.substring(3); 327 if ( testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName) ) { 328 return methods[i]; 329 } 330 331 } 332 333 336 if ( methodName.startsWith("is") ) { 337 String testStdMethod = Introspector.decapitalize( methodName.substring(2) ); 338 String testOldMethod = methodName.substring(2); 339 if ( testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName) ) { 340 return methods[i]; 341 } 342 } 343 } 344 } 345 return null; 346 } 347 348 } 349 | Popular Tags |