1 61 62 package com.opensymphony.workflow.designer.beanutils; 63 64 import java.beans.IntrospectionException ; 65 import java.beans.PropertyDescriptor ; 66 import java.lang.reflect.Method ; 67 import java.lang.reflect.Modifier ; 68 import java.security.AccessController ; 69 import java.security.PrivilegedAction ; 70 71 88 89 public class MappedPropertyDescriptor extends PropertyDescriptor 90 { 91 93 94 private Class mappedPropertyType; 95 96 97 private Method mappedReadMethod; 98 99 100 private Method mappedWriteMethod; 101 102 103 private static final Class [] stringClassArray = new Class []{String .class}; 104 105 107 122 public MappedPropertyDescriptor(String propertyName, Class beanClass) throws IntrospectionException 123 { 124 125 super(propertyName, null, null); 126 127 if(propertyName == null || propertyName.length() == 0) 128 { 129 throw new IntrospectionException ("bad property name: " + propertyName + " on class: " + beanClass.getClass().getName()); 130 } 131 132 setName(propertyName); 133 String base = capitalizePropertyName(propertyName); 134 135 try 137 { 138 mappedReadMethod = findMethod(beanClass, "get" + base, 1, stringClassArray); 139 Class params[] = {String .class, mappedReadMethod.getReturnType()}; 140 mappedWriteMethod = findMethod(beanClass, "set" + base, 2, params); 141 } 142 catch(IntrospectionException e) 143 { 144 ; 145 } 146 147 if(mappedReadMethod == null) 149 { 150 mappedWriteMethod = findMethod(beanClass, "set" + base, 2); 151 } 152 153 if((mappedReadMethod == null) && (mappedWriteMethod == null)) 154 { 155 throw new IntrospectionException ("Property '" + propertyName + "' not found on " + beanClass.getName()); 156 } 157 158 findMappedPropertyType(); 159 } 160 161 177 public MappedPropertyDescriptor(String propertyName, Class beanClass, String mappedGetterName, String mappedSetterName) throws IntrospectionException 178 { 179 180 super(propertyName, null, null); 181 182 if(propertyName == null || propertyName.length() == 0) 183 { 184 throw new IntrospectionException ("bad property name: " + propertyName); 185 } 186 setName(propertyName); 187 188 mappedReadMethod = findMethod(beanClass, mappedGetterName, 1, stringClassArray); 190 191 if(mappedReadMethod != null) 192 { 193 Class params[] = {String .class, mappedReadMethod.getReturnType()}; 194 mappedWriteMethod = findMethod(beanClass, mappedSetterName, 2, params); 195 } 196 else 197 { 198 mappedWriteMethod = findMethod(beanClass, mappedSetterName, 2); 199 } 200 201 findMappedPropertyType(); 202 } 203 204 217 public MappedPropertyDescriptor(String propertyName, Method mappedGetter, Method mappedSetter) throws IntrospectionException 218 { 219 220 super(propertyName, mappedGetter, mappedSetter); 221 222 if(propertyName == null || propertyName.length() == 0) 223 { 224 throw new IntrospectionException ("bad property name: " + propertyName); 225 } 226 227 setName(propertyName); 228 mappedReadMethod = mappedGetter; 229 mappedWriteMethod = mappedSetter; 230 findMappedPropertyType(); 231 } 232 233 235 245 public Class getMappedPropertyType() 246 { 247 return mappedPropertyType; 248 } 249 250 256 public Method getMappedReadMethod() 257 { 258 return mappedReadMethod; 259 } 260 261 266 public void setMappedReadMethod(Method mappedGetter) throws IntrospectionException 267 { 268 mappedReadMethod = mappedGetter; 269 findMappedPropertyType(); 270 } 271 272 278 public Method getMappedWriteMethod() 279 { 280 return mappedWriteMethod; 281 } 282 283 288 public void setMappedWriteMethod(Method mappedSetter) throws IntrospectionException 289 { 290 mappedWriteMethod = mappedSetter; 291 findMappedPropertyType(); 292 } 293 294 296 300 private void findMappedPropertyType() throws IntrospectionException 301 { 302 try 303 { 304 mappedPropertyType = null; 305 if(mappedReadMethod != null) 306 { 307 if(mappedReadMethod.getParameterTypes().length != 1) 308 { 309 throw new IntrospectionException ("bad mapped read method arg count"); 310 } 311 mappedPropertyType = mappedReadMethod.getReturnType(); 312 if(mappedPropertyType == Void.TYPE) 313 { 314 throw new IntrospectionException ("mapped read method " + mappedReadMethod.getName() + " returns void"); 315 } 316 } 317 318 if(mappedWriteMethod != null) 319 { 320 Class params[] = mappedWriteMethod.getParameterTypes(); 321 if(params.length != 2) 322 { 323 throw new IntrospectionException ("bad mapped write method arg count"); 324 } 325 if(mappedPropertyType != null && mappedPropertyType != params[1]) 326 { 327 throw new IntrospectionException ("type mismatch between mapped read and write methods"); 328 } 329 mappedPropertyType = params[1]; 330 } 331 } 332 catch(IntrospectionException ex) 333 { 334 throw ex; 335 } 336 } 337 338 343 private static String capitalizePropertyName(String s) 344 { 345 if(s.length() == 0) 346 { 347 return s; 348 } 349 350 char chars[] = s.toCharArray(); 351 chars[0] = Character.toUpperCase(chars[0]); 352 return new String (chars); 353 } 354 355 359 private static java.util.Hashtable declaredMethodCache = new java.util.Hashtable (); 361 362 365 private static synchronized Method [] getPublicDeclaredMethods(Class clz) 366 { 367 final Class fclz = clz; 370 Method [] result = (Method [])declaredMethodCache.get(fclz); 371 if(result != null) 372 { 373 return result; 374 } 375 376 result = (Method [])AccessController.doPrivileged(new PrivilegedAction () 378 { 379 public Object run() 380 { 381 return fclz.getDeclaredMethods(); 382 } 383 }); 384 385 for(int i = 0; i < result.length; i++) 387 { 388 Method method = result[i]; 389 int mods = method.getModifiers(); 390 if(!Modifier.isPublic(mods)) 391 { 392 result[i] = null; 393 } 394 } 395 396 declaredMethodCache.put(clz, result); 398 return result; 399 } 400 401 404 private static Method internalFindMethod(Class start, String methodName, int argCount) 405 { 406 for(Class cl = start; cl != null; cl = cl.getSuperclass()) 409 { 410 Method methods[] = getPublicDeclaredMethods(cl); 411 for(int i = 0; i < methods.length; i++) 412 { 413 Method method = methods[i]; 414 if(method == null) 415 { 416 continue; 417 } 418 int mods = method.getModifiers(); 420 if(Modifier.isStatic(mods)) 421 { 422 continue; 423 } 424 if(method.getName().equals(methodName) && method.getParameterTypes().length == argCount) 425 { 426 return method; 427 } 428 } 429 } 430 431 Class ifcs[] = start.getInterfaces(); 435 for(int i = 0; i < ifcs.length; i++) 436 { 437 Method m = internalFindMethod(ifcs[i], methodName, argCount); 438 if(m != null) 439 { 440 return m; 441 } 442 } 443 444 return null; 445 } 446 447 451 private static Method internalFindMethod(Class start, String methodName, int argCount, Class args[]) 452 { 453 for(Class cl = start; cl != null; cl = cl.getSuperclass()) 456 { 457 Method methods[] = getPublicDeclaredMethods(cl); 458 for(int i = 0; i < methods.length; i++) 459 { 460 Method method = methods[i]; 461 if(method == null) 462 { 463 continue; 464 } 465 int mods = method.getModifiers(); 467 if(Modifier.isStatic(mods)) 468 { 469 continue; 470 } 471 Class params[] = method.getParameterTypes(); 473 if(method.getName().equals(methodName) && params.length == argCount) 474 { 475 boolean different = false; 476 if(argCount > 0) 477 { 478 for(int j = 0; j < argCount; j++) 479 { 480 if(params[j] != args[j]) 481 { 482 different = true; 483 continue; 484 } 485 } 486 if(different) 487 { 488 continue; 489 } 490 } 491 return method; 492 } 493 } 494 } 495 496 Class ifcs[] = start.getInterfaces(); 500 for(int i = 0; i < ifcs.length; i++) 501 { 502 Method m = internalFindMethod(ifcs[i], methodName, argCount); 503 if(m != null) 504 { 505 return m; 506 } 507 } 508 509 return null; 510 } 511 512 515 static Method findMethod(Class cls, String methodName, int argCount) throws IntrospectionException 516 { 517 if(methodName == null) 518 { 519 return null; 520 } 521 522 Method m = internalFindMethod(cls, methodName, argCount); 523 if(m != null) 524 { 525 return m; 526 } 527 528 throw new IntrospectionException ("No method \"" + methodName + "\" with " + argCount + " arg(s)"); 530 } 531 532 535 static Method findMethod(Class cls, String methodName, int argCount, Class args[]) throws IntrospectionException 536 { 537 if(methodName == null) 538 { 539 return null; 540 } 541 542 Method m = internalFindMethod(cls, methodName, argCount, args); 543 if(m != null) 544 { 545 return m; 546 } 547 548 throw new IntrospectionException ("No method \"" + methodName + "\" with " + argCount + " arg(s) of matching types."); 550 } 551 552 558 static boolean isSubclass(Class a, Class b) 559 { 560 if(a == b) 564 { 565 return true; 566 } 567 568 if(a == null || b == null) 569 { 570 return false; 571 } 572 573 for(Class x = a; x != null; x = x.getSuperclass()) 574 { 575 if(x == b) 576 { 577 return true; 578 } 579 580 if(b.isInterface()) 581 { 582 Class interfaces[] = x.getInterfaces(); 583 for(int i = 0; i < interfaces.length; i++) 584 { 585 if(isSubclass(interfaces[i], b)) 586 { 587 return true; 588 } 589 } 590 } 591 } 592 593 return false; 594 } 595 } 596 | Popular Tags |