1 28 29 package com.caucho.util; 30 31 import com.caucho.vfs.Path; 32 import com.caucho.vfs.Vfs; 33 34 import java.beans.BeanInfo ; 35 import java.beans.PropertyDescriptor ; 36 import java.lang.reflect.Constructor ; 37 import java.lang.reflect.Method ; 38 import java.lang.reflect.Modifier ; 39 import java.util.HashMap ; 40 import java.util.logging.Logger ; 41 42 45 public class BeanUtil { 46 static final Logger log = Log.open(BeanUtil.class); 47 static L10N L = new L10N(BeanUtil.class); 48 49 55 public static Class 56 getBeanPropertyClass(Object obj, String name) 57 { 58 Method method = getBeanPropertyMethod(obj, name); 59 60 if (method == null) 61 return null; 62 63 Class []paramTypes = method.getParameterTypes(); 64 if (paramTypes.length == 1) 65 return paramTypes[0]; 66 else 67 return null; 68 } 69 70 76 public static Method 77 getBeanPropertyMethod(Object obj, String name) 78 { 79 name = configToBeanName(name); 80 81 Class beanClass = obj.getClass(); 82 Method method = getSetMethod(beanClass, name); 83 84 if (method == null) 85 method = getAddMethod(beanClass, name); 86 87 return method; 88 } 89 90 public static void 91 validateClass(Class cl, Class parent) 92 throws RegistryException 93 { 94 if (parent.isAssignableFrom(cl)) { 95 } 96 else if (parent.isInterface()) 97 throw new RegistryException(L.l("{0} must implement {1}", 98 cl.getName(), parent.getName())); 99 else 100 throw new RegistryException(L.l("{0} must extend {1}", 101 cl.getName(), parent.getName())); 102 103 if (cl.isInterface()) 104 throw new RegistryException(L.l("{0} must be a concrete class.", 105 cl.getName())); 106 107 if (Modifier.isAbstract(cl.getModifiers())) 108 throw new RegistryException(L.l("{0} must not be abstract.", 109 cl.getName())); 110 111 if (! Modifier.isPublic(cl.getModifiers())) 112 throw new RegistryException(L.l("{0} must be public.", 113 cl.getName())); 114 115 Constructor zero = null; 116 try { 117 zero = cl.getConstructor(new Class [0]); 118 } catch (Throwable e) { 119 } 120 121 if (zero == null) 122 throw new RegistryException(L.l("{0} must have a public zero-arg constructor.", 123 cl.getName())); 124 } 125 126 136 public static Path lookupPath(String pathName, HashMap varMap, Path pwd) 137 { 138 if (pwd == null) 139 pwd = Vfs.lookup(); 140 141 if (pathName.startsWith("$")) { 142 int p = pathName.indexOf('/'); 143 String prefix; 144 String suffix; 145 146 if (p > 0) { 147 prefix = pathName.substring(1, p); 148 suffix = pathName.substring(p + 1); 149 } 150 else { 151 prefix = pathName.substring(1); 152 suffix = null; 153 } 154 155 Object value = varMap != null ? varMap.get(prefix) : null; 156 if (value instanceof Path) { 157 pwd = (Path) value; 158 pathName = suffix; 159 } 160 } 161 162 if (pathName == null) 163 return pwd; 164 else if (pathName.indexOf('$') < 0) 165 return pwd.lookup(pathName); 166 167 CharBuffer cb = CharBuffer.allocate(); 168 int head = 0; 169 int tail = 0; 170 while ((tail = pathName.indexOf('$', head)) >= 0) { 171 cb.append(pathName.substring(head, tail)); 172 173 if (tail + 1 == pathName.length()) { 174 cb.append('$'); 175 continue; 176 } 177 178 int ch = pathName.charAt(tail + 1); 179 180 if (ch >= '0' && ch <= '9') { 181 for (head = tail + 1; head < pathName.length(); head++) { 182 ch = pathName.charAt(head); 183 184 if (ch < '0' || ch > '9') 185 break; 186 } 187 } 188 else { 189 for (head = tail + 1; head < pathName.length(); head++) { 190 ch = pathName.charAt(head); 191 192 if (ch == '/' || ch == '\\' || ch == '$' || ch == ' ') 193 break; 194 } 195 } 196 197 String key = pathName.substring(tail + 1, head); 198 Object value = varMap != null ? varMap.get(key) : null; 199 200 if (value == null) 201 value = System.getProperty(key); 202 203 if (value != null) 204 cb.append(value); 205 else 206 cb.append(pathName.substring(tail, head)); 207 } 208 209 if (head > 0 && head < pathName.length()) 210 cb.append(pathName.substring(head)); 211 212 return pwd.lookupNative(cb.close()); 213 } 214 215 222 private static String configToBeanName(String name) 223 { 224 CharBuffer cb = CharBuffer.allocate(); 225 226 for (int i = 0; i < name.length(); i++) { 227 char ch = name.charAt(i); 228 229 if (ch == '-') 230 cb.append(Character.toUpperCase(name.charAt(++i))); 231 else 232 cb.append(ch); 233 } 234 235 return cb.close(); 236 } 237 238 241 private static Method getAddMethod(Class cl, String name) 242 { 243 name = "add" + name; 244 245 Method []methods = cl.getMethods(); 246 247 for (int i = 0; i < methods.length; i++) { 248 if (! Modifier.isPublic(methods[i].getModifiers())) 249 continue; 250 251 if (! name.equalsIgnoreCase(methods[i].getName())) 252 continue; 253 254 if (methods[i].getParameterTypes().length == 1) 255 return methods[i]; 256 } 257 258 return null; 259 } 260 261 264 static private Method getMethod(Method []methods, String name) 265 { 266 Method method = null; 267 for (int i = 0; i < methods.length; i++) { 268 method = methods[i]; 269 270 if (! Modifier.isPublic(method.getModifiers())) 271 continue; 272 273 if (! Modifier.isPublic(method.getDeclaringClass().getModifiers())) 274 continue; 275 276 if (method.getName().equals(name)) 277 return method; 278 } 279 280 return null; 281 } 282 283 286 static private Method getMethod(Method []methods, String name, 287 Class []params) 288 { 289 Method method = null; 290 291 loop: 292 for (int i = 0; i < methods.length; i++) { 293 method = methods[i]; 294 295 if (! Modifier.isPublic(method.getModifiers())) 296 continue; 297 298 if (! Modifier.isPublic(method.getDeclaringClass().getModifiers())) 299 continue; 300 301 if (! method.getName().equals(name)) 302 continue; 303 304 Class []actual = method.getParameterTypes(); 305 306 if (actual.length != params.length) 307 continue; 308 309 for (int j = 0; j < actual.length; j++) { 310 if (! actual[j].isAssignableFrom(params[j])) 311 continue loop; 312 } 313 314 return method; 315 } 316 317 return null; 318 } 319 320 323 public static Method getSetMethod(BeanInfo info, String propertyName) 324 { 325 PropertyDescriptor []pds = info.getPropertyDescriptors(); 326 327 Method method = null; 328 for (int i = 0; i < pds.length; i++) { 329 if (pds[i].getName().equals(propertyName) && 330 pds[i].getWriteMethod() != null) { 331 method = pds[i].getWriteMethod(); 332 333 if (method.getParameterTypes()[0].equals(String .class)) 334 return method; 335 } 336 } 337 338 if (method != null) 339 return method; 340 341 return getSetMethod(info.getBeanDescriptor().getBeanClass(), propertyName); 342 } 343 344 347 public static Method getSetMethod(Class cl, String propertyName) 348 { 349 Method method = getSetMethod(cl, propertyName, false); 350 351 if (method != null) 352 return method; 353 354 return getSetMethod(cl, propertyName, true); 355 } 356 357 360 public static Method getSetMethod(Class cl, 361 String propertyName, 362 boolean ignoreCase) 363 { 364 String setName = "set" + propertyNameToMethodName(propertyName); 365 366 Method bestMethod = null; 367 368 for (Class ptrCl = cl; ptrCl != null; ptrCl = ptrCl.getSuperclass()) { 369 Method method = getSetMethod(ptrCl.getMethods(), 370 setName, 371 ignoreCase); 372 373 if (method != null && method.getParameterTypes()[0].equals(String .class)) 374 return method; 375 else if (method != null) 376 bestMethod = method; 377 } 378 379 if (bestMethod != null) 380 return bestMethod; 381 382 Class []interfaces = cl.getInterfaces(); 383 for (int i = 0; i < interfaces.length; i++) { 384 Method method = getSetMethod(interfaces[i].getMethods(), 385 setName, 386 ignoreCase); 387 388 if (method != null && method.getParameterTypes()[0].equals(String .class)) 389 return method; 390 else if (method != null) 391 bestMethod = method; 392 } 393 394 if (bestMethod != null) 395 return bestMethod; 396 397 return null; 398 } 399 400 406 private static Method getSetMethod(Method []methods, 407 String setName, 408 boolean ignoreCase) 409 { 410 for (int i = 0; i < methods.length; i++) { 411 Method method = methods[i]; 412 413 if (! ignoreCase && ! method.getName().equals(setName)) 415 continue; 416 417 if (ignoreCase && ! method.getName().equalsIgnoreCase(setName)) 419 continue; 420 421 if (! Modifier.isPublic(method.getModifiers())) 423 continue; 424 425 if (! Modifier.isPublic(method.getDeclaringClass().getModifiers())) 427 continue; 428 429 if (method.getParameterTypes().length != 1) 431 continue; 432 433 if (method.getReturnType().equals(void.class)) { 435 return method; 436 } 437 } 438 439 return null; 440 } 441 442 445 public static Method getGetMethod(BeanInfo info, String propertyName) 446 { 447 PropertyDescriptor []pds = info.getPropertyDescriptors(); 448 449 for (int i = 0; i < pds.length; i++) { 450 if (pds[i].getName().equals(propertyName) && 451 pds[i].getReadMethod() != null) { 452 if (! Modifier.isPublic(pds[i].getReadMethod().getDeclaringClass().getModifiers())) { 453 try { 454 pds[i].getReadMethod().setAccessible(true); 455 } catch (Throwable e) { 456 continue; 457 } 458 } 459 460 return pds[i].getReadMethod(); 461 } 462 } 463 464 return getGetMethod(info.getBeanDescriptor().getBeanClass(), propertyName); 465 } 466 467 470 public static Method getGetMethod(Class cl, String propertyName) 471 { 472 Method method = getGetMethod(cl, propertyName, false); 473 474 if (method != null) 475 return method; 476 477 return getGetMethod(cl, propertyName, true); 478 } 479 480 483 public static Method getGetMethod(Class cl, 484 String propertyName, 485 boolean ignoreCase) 486 { 487 String getName = "get" + propertyNameToMethodName(propertyName); 488 String isName = "is" + propertyNameToMethodName(propertyName); 489 490 for (Class ptrCl = cl; ptrCl != null; ptrCl = ptrCl.getSuperclass()) { 491 Method method = getGetMethod(ptrCl.getDeclaredMethods(), getName, 492 isName, ignoreCase); 493 494 if (method != null) 495 return method; 496 497 Class []interfaces = ptrCl.getInterfaces(); 498 for (int i = 0; i < interfaces.length; i++) { 499 method = getGetMethod(interfaces[i].getDeclaredMethods(), 500 getName, isName, ignoreCase); 501 502 if (method != null) 503 return method; 504 } 505 } 506 507 return null; 508 } 509 510 516 private static Method getGetMethod(Method []methods, 517 String getName, 518 String isName, 519 boolean ignoreCase) 520 { 521 for (int i = 0; i < methods.length; i++) { 522 Method method = methods[i]; 523 524 if (! Modifier.isPublic(method.getModifiers())) 526 continue; 527 528 if (! Modifier.isPublic(method.getDeclaringClass().getModifiers())) 530 continue; 531 532 if (method.getParameterTypes().length != 0) 534 continue; 535 536 if (method.getReturnType().equals(void.class)) 538 continue; 539 540 else if (! ignoreCase && methods[i].getName().equals(getName)) 542 return methods[i]; 543 544 else if (ignoreCase && methods[i].getName().equalsIgnoreCase(getName)) 546 return methods[i]; 547 548 else if (! methods[i].getReturnType().equals(boolean.class)) 550 continue; 551 552 else if (! ignoreCase && methods[i].getName().equals(isName)) 554 return methods[i]; 555 556 else if (ignoreCase && methods[i].getName().equalsIgnoreCase(isName)) 558 return methods[i]; 559 } 560 561 return null; 562 } 563 564 570 public static String propertyNameToMethodName(String propertyName) 571 { 572 char ch = propertyName.charAt(0); 573 if (Character.isLowerCase(ch)) 574 propertyName = Character.toUpperCase(ch) + propertyName.substring(1); 575 576 return propertyName; 577 } 578 579 585 public static String methodNameToPropertyName(BeanInfo info, 586 String methodName) 587 { 588 PropertyDescriptor []pds = info.getPropertyDescriptors(); 589 590 for (int i = 0; i < pds.length; i++) { 591 if (pds[i].getReadMethod() != null && 592 pds[i].getReadMethod().getName().equals(methodName)) 593 return pds[i].getName(); 594 if (pds[i].getWriteMethod() != null && 595 pds[i].getWriteMethod().getName().equals(methodName)) 596 return pds[i].getName(); 597 } 598 599 return methodNameToPropertyName(methodName); 600 } 601 602 608 public static String methodNameToPropertyName(String methodName) 609 { 610 if (methodName.startsWith("get")) 611 methodName = methodName.substring(3); 612 else if (methodName.startsWith("set")) 613 methodName = methodName.substring(3); 614 else if (methodName.startsWith("is")) 615 methodName = methodName.substring(2); 616 617 if (methodName.length() == 0) 618 return null; 619 620 char ch = methodName.charAt(0); 621 if (Character.isUpperCase(ch) && 622 (methodName.length() == 1 || 623 ! Character.isUpperCase(methodName.charAt(1)))) { 624 methodName = Character.toLowerCase(ch) + methodName.substring(1); 625 } 626 627 return methodName; 628 } 629 } 630 | Popular Tags |