1 16 17 package org.apache.commons.beanutils; 18 19 20 import java.beans.IntrospectionException ; 21 import java.beans.PropertyDescriptor ; 22 import java.lang.reflect.Method ; 23 import java.lang.reflect.Modifier ; 24 import java.security.AccessController ; 25 import java.security.PrivilegedAction ; 26 27 28 45 46 47 public class MappedPropertyDescriptor extends PropertyDescriptor { 48 50 53 private Class mappedPropertyType; 54 55 58 private Method mappedReadMethod; 59 60 63 private Method mappedWriteMethod; 64 65 68 private static final Class [] stringClassArray = new Class []{String .class}; 69 70 72 88 public MappedPropertyDescriptor(String propertyName, Class beanClass) 89 throws IntrospectionException { 90 91 super(propertyName, null, null); 92 93 if (propertyName == null || propertyName.length() == 0) { 94 throw new IntrospectionException ("bad property name: " + 95 propertyName + " on class: " + beanClass.getClass().getName()); 96 } 97 98 setName(propertyName); 99 String base = capitalizePropertyName(propertyName); 100 101 try { 103 mappedReadMethod = findMethod(beanClass, "get" + base, 1, 104 stringClassArray); 105 Class params[] = { String .class, mappedReadMethod.getReturnType() }; 106 mappedWriteMethod = findMethod(beanClass, "set" + base, 2, params); 107 } catch (IntrospectionException e) { 108 ; 109 } 110 111 if (mappedReadMethod == null) { 113 mappedWriteMethod = findMethod(beanClass, "set" + base, 2); 114 } 115 116 if ((mappedReadMethod == null) && (mappedWriteMethod == null)) { 117 throw new IntrospectionException ("Property '" + propertyName + 118 "' not found on " + 119 beanClass.getName()); 120 } 121 122 findMappedPropertyType(); 123 } 124 125 126 143 public MappedPropertyDescriptor(String propertyName, Class beanClass, 144 String mappedGetterName, String mappedSetterName) 145 throws IntrospectionException { 146 147 super(propertyName, null, null); 148 149 if (propertyName == null || propertyName.length() == 0) { 150 throw new IntrospectionException ("bad property name: " + 151 propertyName); 152 } 153 setName(propertyName); 154 155 mappedReadMethod = 157 findMethod(beanClass, mappedGetterName, 1, stringClassArray); 158 159 if (mappedReadMethod != null) { 160 Class params[] = { String .class, mappedReadMethod.getReturnType() }; 161 mappedWriteMethod = 162 findMethod(beanClass, mappedSetterName, 2, params); 163 } else { 164 mappedWriteMethod = 165 findMethod(beanClass, mappedSetterName, 2); 166 } 167 168 findMappedPropertyType(); 169 } 170 171 185 public MappedPropertyDescriptor(String propertyName, 186 Method mappedGetter, Method mappedSetter) 187 throws IntrospectionException { 188 189 super(propertyName, mappedGetter, mappedSetter); 190 191 if (propertyName == null || propertyName.length() == 0) { 192 throw new IntrospectionException ("bad property name: " + 193 propertyName); 194 } 195 196 setName(propertyName); 197 mappedReadMethod = mappedGetter; 198 mappedWriteMethod = mappedSetter; 199 findMappedPropertyType(); 200 } 201 202 204 214 public Class getMappedPropertyType() { 215 return mappedPropertyType; 216 } 217 218 224 public Method getMappedReadMethod() { 225 return mappedReadMethod; 226 } 227 228 233 public void setMappedReadMethod(Method mappedGetter) 234 throws IntrospectionException { 235 mappedReadMethod = mappedGetter; 236 findMappedPropertyType(); 237 } 238 239 245 public Method getMappedWriteMethod() { 246 return mappedWriteMethod; 247 } 248 249 254 public void setMappedWriteMethod(Method mappedSetter) 255 throws IntrospectionException { 256 mappedWriteMethod = mappedSetter; 257 findMappedPropertyType(); 258 } 259 260 262 266 private void findMappedPropertyType() throws IntrospectionException { 267 try { 268 mappedPropertyType = null; 269 if (mappedReadMethod != null) { 270 if (mappedReadMethod.getParameterTypes().length != 1) { 271 throw new IntrospectionException 272 ("bad mapped read method arg count"); 273 } 274 mappedPropertyType = mappedReadMethod.getReturnType(); 275 if (mappedPropertyType == Void.TYPE) { 276 throw new IntrospectionException 277 ("mapped read method " + 278 mappedReadMethod.getName() + " returns void"); 279 } 280 } 281 282 if (mappedWriteMethod != null) { 283 Class params[] = mappedWriteMethod.getParameterTypes(); 284 if (params.length != 2) { 285 throw new IntrospectionException 286 ("bad mapped write method arg count"); 287 } 288 if (mappedPropertyType != null && 289 mappedPropertyType != params[1]) { 290 throw new IntrospectionException 291 ("type mismatch between mapped read and write methods"); 292 } 293 mappedPropertyType = params[1]; 294 } 295 } catch (IntrospectionException ex) { 296 throw ex; 297 } 298 } 299 300 301 306 private static String capitalizePropertyName(String s) { 307 if (s.length() == 0) { 308 return s; 309 } 310 311 char chars[] = s.toCharArray(); 312 chars[0] = Character.toUpperCase(chars[0]); 313 return new String (chars); 314 } 315 316 320 private static java.util.Hashtable 322 declaredMethodCache = new java.util.Hashtable (); 323 324 327 private static synchronized Method [] getPublicDeclaredMethods(Class clz) { 328 final Class fclz = clz; 331 Method [] result = (Method []) declaredMethodCache.get(fclz); 332 if (result != null) { 333 return result; 334 } 335 336 result = (Method []) 338 AccessController.doPrivileged(new PrivilegedAction () { 339 public Object run() { 340 try{ 341 342 return fclz.getDeclaredMethods(); 343 344 } catch (SecurityException ex) { 345 Method [] methods = fclz.getMethods(); 350 for (int i = 0, size = methods.length; i < size; i++) { 351 Method method = methods[i]; 352 if (!(fclz.equals(method.getDeclaringClass()))) { 353 methods[i] = null; 354 } 355 } 356 return methods; 357 } 358 } 359 }); 360 361 for (int i = 0; i < result.length; i++) { 363 Method method = result[i]; 364 if (method != null) { 365 int mods = method.getModifiers(); 366 if (!Modifier.isPublic(mods)) { 367 result[i] = null; 368 } 369 } 370 } 371 372 declaredMethodCache.put(clz, result); 374 return result; 375 } 376 377 380 private static Method internalFindMethod(Class start, String methodName, 381 int argCount) { 382 for (Class cl = start; cl != null; cl = cl.getSuperclass()) { 385 Method methods[] = getPublicDeclaredMethods(cl); 386 for (int i = 0; i < methods.length; i++) { 387 Method method = methods[i]; 388 if (method == null) { 389 continue; 390 } 391 int mods = method.getModifiers(); 393 if (Modifier.isStatic(mods)) { 394 continue; 395 } 396 if (method.getName().equals(methodName) && 397 method.getParameterTypes().length == argCount) { 398 return method; 399 } 400 } 401 } 402 403 Class ifcs[] = start.getInterfaces(); 407 for (int i = 0; i < ifcs.length; i++) { 408 Method m = internalFindMethod(ifcs[i], methodName, argCount); 409 if (m != null) { 410 return m; 411 } 412 } 413 414 return null; 415 } 416 417 421 private static Method internalFindMethod(Class start, String methodName, 422 int argCount, Class args[]) { 423 for (Class cl = start; cl != null; cl = cl.getSuperclass()) { 426 Method methods[] = getPublicDeclaredMethods(cl); 427 for (int i = 0; i < methods.length; i++) { 428 Method method = methods[i]; 429 if (method == null) { 430 continue; 431 } 432 int mods = method.getModifiers(); 434 if (Modifier.isStatic(mods)) { 435 continue; 436 } 437 Class params[] = method.getParameterTypes(); 439 if (method.getName().equals(methodName) && 440 params.length == argCount) { 441 boolean different = false; 442 if (argCount > 0) { 443 for (int j = 0; j < argCount; j++) { 444 if (params[j] != args[j]) { 445 different = true; 446 continue; 447 } 448 } 449 if (different) { 450 continue; 451 } 452 } 453 return method; 454 } 455 } 456 } 457 458 Class ifcs[] = start.getInterfaces(); 462 for (int i = 0; i < ifcs.length; i++) { 463 Method m = internalFindMethod(ifcs[i], methodName, argCount); 464 if (m != null) { 465 return m; 466 } 467 } 468 469 return null; 470 } 471 472 475 static Method findMethod(Class cls, String methodName, int argCount) 476 throws IntrospectionException { 477 if (methodName == null) { 478 return null; 479 } 480 481 Method m = internalFindMethod(cls, methodName, argCount); 482 if (m != null) { 483 return m; 484 } 485 486 throw new IntrospectionException ("No method \"" + methodName + 488 "\" with " + argCount + " arg(s)"); 489 } 490 491 494 static Method findMethod(Class cls, String methodName, int argCount, 495 Class args[]) throws IntrospectionException { 496 if (methodName == null) { 497 return null; 498 } 499 500 Method m = internalFindMethod(cls, methodName, argCount, args); 501 if (m != null) { 502 return m; 503 } 504 505 throw new IntrospectionException ("No method \"" + methodName + 507 "\" with " + argCount + " arg(s) of matching types."); 508 } 509 510 516 static boolean isSubclass(Class a, Class b) { 517 if (a == b) { 521 return true; 522 } 523 524 if (a == null || b == null) { 525 return false; 526 } 527 528 for (Class x = a; x != null; x = x.getSuperclass()) { 529 if (x == b) { 530 return true; 531 } 532 533 if (b.isInterface()) { 534 Class interfaces[] = x.getInterfaces(); 535 for (int i = 0; i < interfaces.length; i++) { 536 if (isSubclass(interfaces[i], b)) { 537 return true; 538 } 539 } 540 } 541 } 542 543 return false; 544 } 545 546 547 550 551 private boolean throwsException(Method method, Class exception) { 552 553 Class exs[] = method.getExceptionTypes(); 554 for (int i = 0; i < exs.length; i++) { 555 if (exs[i] == exception) { 556 return true; 557 } 558 } 559 560 return false; 561 } 562 } 563 | Popular Tags |