1 16 17 package org.apache.commons.beanutils; 18 19 20 import java.beans.BeanInfo ; 21 import java.beans.IndexedPropertyDescriptor ; 22 import java.beans.IntrospectionException ; 23 import java.beans.Introspector ; 24 import java.beans.PropertyDescriptor ; 25 import java.lang.reflect.Array ; 26 import java.lang.reflect.InvocationTargetException ; 27 import java.lang.reflect.Method ; 28 import java.util.HashMap ; 29 import java.util.Iterator ; 30 import java.util.List ; 31 import java.util.Map ; 32 33 import org.apache.commons.collections.FastHashMap; 34 import org.apache.commons.logging.Log; 35 import org.apache.commons.logging.LogFactory; 36 37 38 95 96 public class PropertyUtilsBean { 97 98 100 protected static PropertyUtilsBean getInstance() { 101 return BeanUtilsBean.getInstance().getPropertyUtils(); 102 } 103 104 106 110 private FastHashMap descriptorsCache = null; 111 private FastHashMap mappedDescriptorsCache = null; 112 113 114 private Log log = LogFactory.getLog(PropertyUtils.class); 115 116 118 119 public PropertyUtilsBean() { 120 descriptorsCache = new FastHashMap(); 121 descriptorsCache.setFast(true); 122 mappedDescriptorsCache = new FastHashMap(); 123 mappedDescriptorsCache.setFast(true); 124 } 125 126 127 129 130 135 public void clearDescriptors() { 136 137 descriptorsCache.clear(); 138 mappedDescriptorsCache.clear(); 139 Introspector.flushCaches(); 140 141 } 142 143 144 172 public void copyProperties(Object dest, Object orig) 173 throws IllegalAccessException , InvocationTargetException , 174 NoSuchMethodException { 175 176 if (dest == null) { 177 throw new IllegalArgumentException 178 ("No destination bean specified"); 179 } 180 if (orig == null) { 181 throw new IllegalArgumentException ("No origin bean specified"); 182 } 183 184 if (orig instanceof DynaBean) { 185 DynaProperty origDescriptors[] = 186 ((DynaBean) orig).getDynaClass().getDynaProperties(); 187 for (int i = 0; i < origDescriptors.length; i++) { 188 String name = origDescriptors[i].getName(); 189 if (dest instanceof DynaBean) { 190 if (isWriteable(dest, name)) { 191 Object value = ((DynaBean) orig).get(name); 192 ((DynaBean) dest).set(name, value); 193 } 194 } else { 195 if (isWriteable(dest, name)) { 196 Object value = ((DynaBean) orig).get(name); 197 setSimpleProperty(dest, name, value); 198 } 199 } 200 } 201 } else if (orig instanceof Map ) { 202 Iterator names = ((Map ) orig).keySet().iterator(); 203 while (names.hasNext()) { 204 String name = (String ) names.next(); 205 if (dest instanceof DynaBean) { 206 if (isWriteable(dest, name)) { 207 Object value = ((Map ) orig).get(name); 208 ((DynaBean) dest).set(name, value); 209 } 210 } else { 211 if (isWriteable(dest, name)) { 212 Object value = ((Map ) orig).get(name); 213 setSimpleProperty(dest, name, value); 214 } 215 } 216 } 217 } else { 218 PropertyDescriptor origDescriptors[] = 219 getPropertyDescriptors(orig); 220 for (int i = 0; i < origDescriptors.length; i++) { 221 String name = origDescriptors[i].getName(); 222 if (isReadable(orig, name)) { 223 if (dest instanceof DynaBean) { 224 if (isWriteable(dest, name)) { 225 Object value = getSimpleProperty(orig, name); 226 ((DynaBean) dest).set(name, value); 227 } 228 } else { 229 if (isWriteable(dest, name)) { 230 Object value = getSimpleProperty(orig, name); 231 setSimpleProperty(dest, name, value); 232 } 233 } 234 } 235 } 236 } 237 238 } 239 240 241 259 public Map describe(Object bean) 260 throws IllegalAccessException , InvocationTargetException , 261 NoSuchMethodException { 262 263 if (bean == null) { 264 throw new IllegalArgumentException ("No bean specified"); 265 } 266 Map description = new HashMap (); 267 if (bean instanceof DynaBean) { 268 DynaProperty descriptors[] = 269 ((DynaBean) bean).getDynaClass().getDynaProperties(); 270 for (int i = 0; i < descriptors.length; i++) { 271 String name = descriptors[i].getName(); 272 description.put(name, getProperty(bean, name)); 273 } 274 } else { 275 PropertyDescriptor descriptors[] = 276 getPropertyDescriptors(bean); 277 for (int i = 0; i < descriptors.length; i++) { 278 String name = descriptors[i].getName(); 279 if (descriptors[i].getReadMethod() != null) 280 description.put(name, getProperty(bean, name)); 281 } 282 } 283 return (description); 284 285 } 286 287 288 311 public Object getIndexedProperty(Object bean, String name) 312 throws IllegalAccessException , InvocationTargetException , 313 NoSuchMethodException { 314 315 if (bean == null) { 316 throw new IllegalArgumentException ("No bean specified"); 317 } 318 if (name == null) { 319 throw new IllegalArgumentException ("No name specified"); 320 } 321 322 int delim = name.indexOf(PropertyUtils.INDEXED_DELIM); 324 int delim2 = name.indexOf(PropertyUtils.INDEXED_DELIM2); 325 if ((delim < 0) || (delim2 <= delim)) { 326 throw new IllegalArgumentException ("Invalid indexed property '" + 327 name + "'"); 328 } 329 int index = -1; 330 try { 331 String subscript = name.substring(delim + 1, delim2); 332 index = Integer.parseInt(subscript); 333 } catch (NumberFormatException e) { 334 throw new IllegalArgumentException ("Invalid indexed property '" + 335 name + "'"); 336 } 337 name = name.substring(0, delim); 338 339 return (getIndexedProperty(bean, name, index)); 341 342 } 343 344 345 366 public Object getIndexedProperty(Object bean, 367 String name, int index) 368 throws IllegalAccessException , InvocationTargetException , 369 NoSuchMethodException { 370 371 if (bean == null) { 372 throw new IllegalArgumentException ("No bean specified"); 373 } 374 if (name == null) { 375 throw new IllegalArgumentException ("No name specified"); 376 } 377 378 if (bean instanceof DynaBean) { 380 DynaProperty descriptor = 381 ((DynaBean) bean).getDynaClass().getDynaProperty(name); 382 if (descriptor == null) { 383 throw new NoSuchMethodException ("Unknown property '" + 384 name + "'"); 385 } 386 return (((DynaBean) bean).get(name, index)); 387 } 388 389 PropertyDescriptor descriptor = 391 getPropertyDescriptor(bean, name); 392 if (descriptor == null) { 393 throw new NoSuchMethodException ("Unknown property '" + 394 name + "'"); 395 } 396 397 if (descriptor instanceof IndexedPropertyDescriptor ) { 399 Method readMethod = ((IndexedPropertyDescriptor ) descriptor). 400 getIndexedReadMethod(); 401 if (readMethod != null) { 402 Object subscript[] = new Object [1]; 403 subscript[0] = new Integer (index); 404 try { 405 return (invokeMethod(readMethod,bean, subscript)); 406 } catch (InvocationTargetException e) { 407 if (e.getTargetException() instanceof 408 ArrayIndexOutOfBoundsException ) { 409 throw (ArrayIndexOutOfBoundsException ) 410 e.getTargetException(); 411 } else { 412 throw e; 413 } 414 } 415 } 416 } 417 418 Method readMethod = getReadMethod(descriptor); 420 if (readMethod == null) { 421 throw new NoSuchMethodException ("Property '" + name + 422 "' has no getter method"); 423 } 424 425 Object value = invokeMethod(readMethod, bean, new Object [0]); 427 if (!value.getClass().isArray()) { 428 if (!(value instanceof java.util.List )) { 429 throw new IllegalArgumentException ("Property '" + name 430 + "' is not indexed"); 431 } else { 432 return ((java.util.List ) value).get(index); 434 } 435 } else { 436 return (Array.get(value, index)); 438 } 439 440 } 441 442 443 461 public Object getMappedProperty(Object bean, String name) 462 throws IllegalAccessException , InvocationTargetException , 463 NoSuchMethodException { 464 465 if (bean == null) { 466 throw new IllegalArgumentException ("No bean specified"); 467 } 468 if (name == null) { 469 throw new IllegalArgumentException ("No name specified"); 470 } 471 472 int delim = name.indexOf(PropertyUtils.MAPPED_DELIM); 474 int delim2 = name.indexOf(PropertyUtils.MAPPED_DELIM2); 475 if ((delim < 0) || (delim2 <= delim)) { 476 throw new IllegalArgumentException 477 ("Invalid mapped property '" + name + "'"); 478 } 479 480 String key = name.substring(delim + 1, delim2); 482 name = name.substring(0, delim); 483 484 return (getMappedProperty(bean, name, key)); 486 487 } 488 489 490 505 public Object getMappedProperty(Object bean, 506 String name, String key) 507 throws IllegalAccessException , InvocationTargetException , 508 NoSuchMethodException { 509 510 if (bean == null) { 511 throw new IllegalArgumentException ("No bean specified"); 512 } 513 if (name == null) { 514 throw new IllegalArgumentException ("No name specified"); 515 } 516 if (key == null) { 517 throw new IllegalArgumentException ("No key specified"); 518 } 519 520 if (bean instanceof DynaBean) { 522 DynaProperty descriptor = 523 ((DynaBean) bean).getDynaClass().getDynaProperty(name); 524 if (descriptor == null) { 525 throw new NoSuchMethodException ("Unknown property '" + 526 name + "'"); 527 } 528 return (((DynaBean) bean).get(name, key)); 529 } 530 531 Object result = null; 532 533 PropertyDescriptor descriptor = getPropertyDescriptor(bean, name); 535 if (descriptor == null) { 536 throw new NoSuchMethodException ("Unknown property '" + 537 name + "'"); 538 } 539 540 if (descriptor instanceof MappedPropertyDescriptor) { 541 Method readMethod = ((MappedPropertyDescriptor) descriptor). 543 getMappedReadMethod(); 544 if (readMethod != null) { 545 Object keyArray[] = new Object [1]; 546 keyArray[0] = key; 547 result = invokeMethod(readMethod, bean, keyArray); 548 } else { 549 throw new NoSuchMethodException ("Property '" + name + 550 "' has no mapped getter method"); 551 } 552 } else { 553 554 Method readMethod = descriptor.getReadMethod(); 555 if (readMethod != null) { 556 Object invokeResult = invokeMethod(readMethod, bean, new Object [0]); 557 558 if (invokeResult instanceof java.util.Map ) { 559 result = ((java.util.Map )invokeResult).get(key); 560 } 561 } else { 562 throw new NoSuchMethodException ("Property '" + name + 563 "' has no mapped getter method"); 564 } 565 } 566 return result; 567 568 } 569 570 571 579 public FastHashMap getMappedPropertyDescriptors(Class beanClass) { 580 581 if (beanClass == null) { 582 return null; 583 } 584 585 return (FastHashMap) mappedDescriptorsCache.get(beanClass); 587 588 } 589 590 591 599 public FastHashMap getMappedPropertyDescriptors(Object bean) { 600 601 if (bean == null) { 602 return null; 603 } 604 return (getMappedPropertyDescriptors(bean.getClass())); 605 606 } 607 608 609 627 public Object getNestedProperty(Object bean, String name) 628 throws IllegalAccessException , InvocationTargetException , 629 NoSuchMethodException { 630 631 if (bean == null) { 632 throw new IllegalArgumentException ("No bean specified"); 633 } 634 if (name == null) { 635 throw new IllegalArgumentException ("No name specified"); 636 } 637 638 int indexOfINDEXED_DELIM = -1; 639 int indexOfMAPPED_DELIM = -1; 640 int indexOfMAPPED_DELIM2 = -1; 641 int indexOfNESTED_DELIM = -1; 642 while (true) { 643 indexOfNESTED_DELIM = name.indexOf(PropertyUtils.NESTED_DELIM); 644 indexOfMAPPED_DELIM = name.indexOf(PropertyUtils.MAPPED_DELIM); 645 indexOfMAPPED_DELIM2 = name.indexOf(PropertyUtils.MAPPED_DELIM2); 646 if (indexOfMAPPED_DELIM2 >= 0 && indexOfMAPPED_DELIM >=0 && 647 (indexOfNESTED_DELIM < 0 || indexOfNESTED_DELIM > indexOfMAPPED_DELIM)) { 648 indexOfNESTED_DELIM = 649 name.indexOf(PropertyUtils.NESTED_DELIM, indexOfMAPPED_DELIM2); 650 } else { 651 indexOfNESTED_DELIM = name.indexOf(PropertyUtils.NESTED_DELIM); 652 } 653 if (indexOfNESTED_DELIM < 0) { 654 break; 655 } 656 String next = name.substring(0, indexOfNESTED_DELIM); 657 indexOfINDEXED_DELIM = next.indexOf(PropertyUtils.INDEXED_DELIM); 658 indexOfMAPPED_DELIM = next.indexOf(PropertyUtils.MAPPED_DELIM); 659 if (bean instanceof Map ) { 660 bean = ((Map ) bean).get(next); 661 } else if (indexOfMAPPED_DELIM >= 0) { 662 bean = getMappedProperty(bean, next); 663 } else if (indexOfINDEXED_DELIM >= 0) { 664 bean = getIndexedProperty(bean, next); 665 } else { 666 bean = getSimpleProperty(bean, next); 667 } 668 if (bean == null) { 669 throw new NestedNullException 670 ("Null property value for '" + 671 name.substring(0, indexOfNESTED_DELIM) + "'"); 672 } 673 name = name.substring(indexOfNESTED_DELIM + 1); 674 } 675 676 indexOfINDEXED_DELIM = name.indexOf(PropertyUtils.INDEXED_DELIM); 677 indexOfMAPPED_DELIM = name.indexOf(PropertyUtils.MAPPED_DELIM); 678 679 if (bean instanceof Map ) { 680 bean = ((Map ) bean).get(name); 681 } else if (indexOfMAPPED_DELIM >= 0) { 682 bean = getMappedProperty(bean, name); 683 } else if (indexOfINDEXED_DELIM >= 0) { 684 bean = getIndexedProperty(bean, name); 685 } else { 686 bean = getSimpleProperty(bean, name); 687 } 688 return bean; 689 690 } 691 692 693 711 public Object getProperty(Object bean, String name) 712 throws IllegalAccessException , InvocationTargetException , 713 NoSuchMethodException { 714 715 return (getNestedProperty(bean, name)); 716 717 } 718 719 720 745 public PropertyDescriptor getPropertyDescriptor(Object bean, 746 String name) 747 throws IllegalAccessException , InvocationTargetException , 748 NoSuchMethodException { 749 750 if (bean == null) { 751 throw new IllegalArgumentException ("No bean specified"); 752 } 753 if (name == null) { 754 throw new IllegalArgumentException ("No name specified"); 755 } 756 757 while (true) { 759 int period = findNextNestedIndex(name); 760 if (period < 0) { 761 break; 762 } 763 String next = name.substring(0, period); 764 int indexOfINDEXED_DELIM = next.indexOf(PropertyUtils.INDEXED_DELIM); 765 int indexOfMAPPED_DELIM = next.indexOf(PropertyUtils.MAPPED_DELIM); 766 if (indexOfMAPPED_DELIM >= 0 && 767 (indexOfINDEXED_DELIM < 0 || 768 indexOfMAPPED_DELIM < indexOfINDEXED_DELIM)) { 769 bean = getMappedProperty(bean, next); 770 } else { 771 if (indexOfINDEXED_DELIM >= 0) { 772 bean = getIndexedProperty(bean, next); 773 } else { 774 bean = getSimpleProperty(bean, next); 775 } 776 } 777 if (bean == null) { 778 throw new IllegalArgumentException 779 ("Null property value for '" + 780 name.substring(0, period) + "'"); 781 } 782 name = name.substring(period + 1); 783 } 784 785 int left = name.indexOf(PropertyUtils.INDEXED_DELIM); 787 if (left >= 0) { 788 name = name.substring(0, left); 789 } 790 left = name.indexOf(PropertyUtils.MAPPED_DELIM); 791 if (left >= 0) { 792 name = name.substring(0, left); 793 } 794 795 if ((bean == null) || (name == null)) { 798 return (null); 799 } 800 801 PropertyDescriptor descriptors[] = getPropertyDescriptors(bean); 802 if (descriptors != null) { 803 804 for (int i = 0; i < descriptors.length; i++) { 805 if (name.equals(descriptors[i].getName())) 806 return (descriptors[i]); 807 } 808 } 809 810 PropertyDescriptor result = null; 811 FastHashMap mappedDescriptors = 812 getMappedPropertyDescriptors(bean); 813 if (mappedDescriptors == null) { 814 mappedDescriptors = new FastHashMap(); 815 mappedDescriptors.setFast(true); 816 mappedDescriptorsCache.put(bean.getClass(), mappedDescriptors); 817 } 818 result = (PropertyDescriptor ) mappedDescriptors.get(name); 819 if (result == null) { 820 try { 822 result = 823 new MappedPropertyDescriptor(name, bean.getClass()); 824 } catch (IntrospectionException ie) { 825 } 826 if (result != null) { 827 mappedDescriptors.put(name, result); 828 } 829 } 830 831 return result; 832 833 } 834 835 private int findNextNestedIndex(String expression) 836 { 837 int bracketCount = 0; 840 for (int i=0, size=expression.length(); i<size ; i++) { 841 char at = expression.charAt(i); 842 switch (at) { 843 case PropertyUtils.NESTED_DELIM: 844 if (bracketCount < 1) { 845 return i; 846 } 847 break; 848 849 case PropertyUtils.MAPPED_DELIM: 850 case PropertyUtils.INDEXED_DELIM: 851 ++bracketCount; 853 break; 854 855 case PropertyUtils.MAPPED_DELIM2: 856 case PropertyUtils.INDEXED_DELIM2: 857 --bracketCount; 859 break; 860 } 861 } 862 return -1; 864 } 865 866 867 878 public PropertyDescriptor [] 879 getPropertyDescriptors(Class beanClass) { 880 881 if (beanClass == null) { 882 throw new IllegalArgumentException ("No bean class specified"); 883 } 884 885 PropertyDescriptor descriptors[] = null; 887 descriptors = 888 (PropertyDescriptor []) descriptorsCache.get(beanClass); 889 if (descriptors != null) { 890 return (descriptors); 891 } 892 893 BeanInfo beanInfo = null; 895 try { 896 beanInfo = Introspector.getBeanInfo(beanClass); 897 } catch (IntrospectionException e) { 898 return (new PropertyDescriptor [0]); 899 } 900 descriptors = beanInfo.getPropertyDescriptors(); 901 if (descriptors == null) { 902 descriptors = new PropertyDescriptor [0]; 903 } 904 descriptorsCache.put(beanClass, descriptors); 905 return (descriptors); 906 907 } 908 909 910 921 public PropertyDescriptor [] getPropertyDescriptors(Object bean) { 922 923 if (bean == null) { 924 throw new IllegalArgumentException ("No bean specified"); 925 } 926 return (getPropertyDescriptors(bean.getClass())); 927 928 } 929 930 931 960 public Class getPropertyEditorClass(Object bean, String name) 961 throws IllegalAccessException , InvocationTargetException , 962 NoSuchMethodException { 963 964 if (bean == null) { 965 throw new IllegalArgumentException ("No bean specified"); 966 } 967 if (name == null) { 968 throw new IllegalArgumentException ("No name specified"); 969 } 970 971 PropertyDescriptor descriptor = 972 getPropertyDescriptor(bean, name); 973 if (descriptor != null) { 974 return (descriptor.getPropertyEditorClass()); 975 } else { 976 return (null); 977 } 978 979 } 980 981 982 1006 public Class getPropertyType(Object bean, String name) 1007 throws IllegalAccessException , InvocationTargetException , 1008 NoSuchMethodException { 1009 1010 if (bean == null) { 1011 throw new IllegalArgumentException ("No bean specified"); 1012 } 1013 if (name == null) { 1014 throw new IllegalArgumentException ("No name specified"); 1015 } 1016 1017 if (bean instanceof DynaBean) { 1019 DynaProperty descriptor = 1020 ((DynaBean) bean).getDynaClass().getDynaProperty(name); 1021 if (descriptor == null) { 1022 return (null); 1023 } 1024 Class type = descriptor.getType(); 1025 if (type == null) { 1026 return (null); 1027 } else if (type.isArray()) { 1028 return (type.getComponentType()); 1029 } else { 1030 return (type); 1031 } 1032 } 1033 1034 PropertyDescriptor descriptor = 1035 getPropertyDescriptor(bean, name); 1036 if (descriptor == null) { 1037 return (null); 1038 } else if (descriptor instanceof IndexedPropertyDescriptor ) { 1039 return (((IndexedPropertyDescriptor ) descriptor). 1040 getIndexedPropertyType()); 1041 } else if (descriptor instanceof MappedPropertyDescriptor) { 1042 return (((MappedPropertyDescriptor) descriptor). 1043 getMappedPropertyType()); 1044 } else { 1045 return (descriptor.getPropertyType()); 1046 } 1047 1048 } 1049 1050 1051 1059 public Method getReadMethod(PropertyDescriptor descriptor) { 1060 1061 return (MethodUtils.getAccessibleMethod(descriptor.getReadMethod())); 1062 1063 } 1064 1065 1066 1084 public Object getSimpleProperty(Object bean, String name) 1085 throws IllegalAccessException , InvocationTargetException , 1086 NoSuchMethodException { 1087 1088 if (bean == null) { 1089 throw new IllegalArgumentException ("No bean specified"); 1090 } 1091 if (name == null) { 1092 throw new IllegalArgumentException ("No name specified"); 1093 } 1094 1095 if (name.indexOf(PropertyUtils.NESTED_DELIM) >= 0) { 1097 throw new IllegalArgumentException 1098 ("Nested property names are not allowed"); 1099 } else if (name.indexOf(PropertyUtils.INDEXED_DELIM) >= 0) { 1100 throw new IllegalArgumentException 1101 ("Indexed property names are not allowed"); 1102 } else if (name.indexOf(PropertyUtils.MAPPED_DELIM) >= 0) { 1103 throw new IllegalArgumentException 1104 ("Mapped property names are not allowed"); 1105 } 1106 1107 if (bean instanceof DynaBean) { 1109 DynaProperty descriptor = 1110 ((DynaBean) bean).getDynaClass().getDynaProperty(name); 1111 if (descriptor == null) { 1112 throw new NoSuchMethodException ("Unknown property '" + 1113 name + "'"); 1114 } 1115 return (((DynaBean) bean).get(name)); 1116 } 1117 1118 PropertyDescriptor descriptor = 1120 getPropertyDescriptor(bean, name); 1121 if (descriptor == null) { 1122 throw new NoSuchMethodException ("Unknown property '" + 1123 name + "'"); 1124 } 1125 Method readMethod = getReadMethod(descriptor); 1126 if (readMethod == null) { 1127 throw new NoSuchMethodException ("Property '" + name + 1128 "' has no getter method"); 1129 } 1130 1131 Object value = invokeMethod(readMethod, bean, new Object [0]); 1133 return (value); 1134 1135 } 1136 1137 1138 1146 public Method getWriteMethod(PropertyDescriptor descriptor) { 1147 1148 return (MethodUtils.getAccessibleMethod(descriptor.getWriteMethod())); 1149 1150 } 1151 1152 1153 1166 public boolean isReadable(Object bean, String name) { 1167 1168 if (bean == null) { 1170 throw new IllegalArgumentException ("No bean specified"); 1171 } 1172 if (name == null) { 1173 throw new IllegalArgumentException ("No name specified"); 1174 } 1175 1176 if (bean instanceof DynaBean) { 1178 return (((DynaBean) bean).getDynaClass().getDynaProperty(name) != null); 1180 } else { 1181 try { 1182 PropertyDescriptor desc = 1183 getPropertyDescriptor(bean, name); 1184 if (desc != null) { 1185 Method readMethod = desc.getReadMethod(); 1186 if ((readMethod == null) && 1187 (desc instanceof IndexedPropertyDescriptor )) { 1188 readMethod = ((IndexedPropertyDescriptor ) desc).getIndexedReadMethod(); 1189 } 1190 return (readMethod != null); 1191 } else { 1192 return (false); 1193 } 1194 } catch (IllegalAccessException e) { 1195 return (false); 1196 } catch (InvocationTargetException e) { 1197 return (false); 1198 } catch (NoSuchMethodException e) { 1199 return (false); 1200 } 1201 } 1202 1203 } 1204 1205 1206 1219 public boolean isWriteable(Object bean, String name) { 1220 1221 if (bean == null) { 1223 throw new IllegalArgumentException ("No bean specified"); 1224 } 1225 if (name == null) { 1226 throw new IllegalArgumentException ("No name specified"); 1227 } 1228 1229 if (bean instanceof DynaBean) { 1231 return (((DynaBean) bean).getDynaClass().getDynaProperty(name) != null); 1233 } else { 1234 try { 1235 PropertyDescriptor desc = 1236 getPropertyDescriptor(bean, name); 1237 if (desc != null) { 1238 Method writeMethod = desc.getWriteMethod(); 1239 if ((writeMethod == null) && 1240 (desc instanceof IndexedPropertyDescriptor )) { 1241 writeMethod = ((IndexedPropertyDescriptor ) desc).getIndexedWriteMethod(); 1242 } 1243 return (writeMethod != null); 1244 } else { 1245 return (false); 1246 } 1247 } catch (IllegalAccessException e) { 1248 return (false); 1249 } catch (InvocationTargetException e) { 1250 return (false); 1251 } catch (NoSuchMethodException e) { 1252 return (false); 1253 } 1254 } 1255 1256 } 1257 1258 1259 1284 public void setIndexedProperty(Object bean, String name, 1285 Object value) 1286 throws IllegalAccessException , InvocationTargetException , 1287 NoSuchMethodException { 1288 1289 if (bean == null) { 1290 throw new IllegalArgumentException ("No bean specified"); 1291 } 1292 if (name == null) { 1293 throw new IllegalArgumentException ("No name specified"); 1294 } 1295 1296 int delim = name.indexOf(PropertyUtils.INDEXED_DELIM); 1298 int delim2 = name.indexOf(PropertyUtils.INDEXED_DELIM2); 1299 if ((delim < 0) || (delim2 <= delim)) { 1300 throw new IllegalArgumentException ("Invalid indexed property '" + 1301 name + "'"); 1302 } 1303 int index = -1; 1304 try { 1305 String subscript = name.substring(delim + 1, delim2); 1306 index = Integer.parseInt(subscript); 1307 } catch (NumberFormatException e) { 1308 throw new IllegalArgumentException ("Invalid indexed property '" + 1309 name + "'"); 1310 } 1311 name = name.substring(0, delim); 1312 1313 setIndexedProperty(bean, name, index, value); 1315 1316 } 1317 1318 1319 1341 public void setIndexedProperty(Object bean, String name, 1342 int index, Object value) 1343 throws IllegalAccessException , InvocationTargetException , 1344 NoSuchMethodException { 1345 1346 if (bean == null) { 1347 throw new IllegalArgumentException ("No bean specified"); 1348 } 1349 if (name == null) { 1350 throw new IllegalArgumentException ("No name specified"); 1351 } 1352 1353 if (bean instanceof DynaBean) { 1355 DynaProperty descriptor = 1356 ((DynaBean) bean).getDynaClass().getDynaProperty(name); 1357 if (descriptor == null) { 1358 throw new NoSuchMethodException ("Unknown property '" + 1359 name + "'"); 1360 } 1361 ((DynaBean) bean).set(name, index, value); 1362 return; 1363 } 1364 1365 PropertyDescriptor descriptor = 1367 getPropertyDescriptor(bean, name); 1368 if (descriptor == null) { 1369 throw new NoSuchMethodException ("Unknown property '" + 1370 name + "'"); 1371 } 1372 1373 if (descriptor instanceof IndexedPropertyDescriptor ) { 1375 Method writeMethod = ((IndexedPropertyDescriptor ) descriptor). 1376 getIndexedWriteMethod(); 1377 if (writeMethod != null) { 1378 Object subscript[] = new Object [2]; 1379 subscript[0] = new Integer (index); 1380 subscript[1] = value; 1381 try { 1382 if (log.isTraceEnabled()) { 1383 String valueClassName = 1384 value == null ? "<null>" 1385 : value.getClass().getName(); 1386 log.trace("setSimpleProperty: Invoking method " 1387 + writeMethod +" with index=" + index 1388 + ", value=" + value 1389 + " (class " + valueClassName+ ")"); 1390 } 1391 invokeMethod(writeMethod, bean, subscript); 1392 } catch (InvocationTargetException e) { 1393 if (e.getTargetException() instanceof 1394 ArrayIndexOutOfBoundsException ) { 1395 throw (ArrayIndexOutOfBoundsException ) 1396 e.getTargetException(); 1397 } else { 1398 throw e; 1399 } 1400 } 1401 return; 1402 } 1403 } 1404 1405 Method readMethod = descriptor.getReadMethod(); 1407 if (readMethod == null) { 1408 throw new NoSuchMethodException ("Property '" + name + 1409 "' has no getter method"); 1410 } 1411 1412 Object array = invokeMethod(readMethod, bean, new Object [0]); 1414 if (!array.getClass().isArray()) { 1415 if (array instanceof List ) { 1416 ((List ) array).set(index, value); 1418 } else { 1419 throw new IllegalArgumentException ("Property '" + name + 1420 "' is not indexed"); 1421 } 1422 } else { 1423 Array.set(array, index, value); 1425 } 1426 1427 } 1428 1429 1430 1449 public void setMappedProperty(Object bean, String name, 1450 Object value) 1451 throws IllegalAccessException , InvocationTargetException , 1452 NoSuchMethodException { 1453 1454 if (bean == null) { 1455 throw new IllegalArgumentException ("No bean specified"); 1456 } 1457 if (name == null) { 1458 throw new IllegalArgumentException ("No name specified"); 1459 } 1460 1461 int delim = name.indexOf(PropertyUtils.MAPPED_DELIM); 1463 int delim2 = name.indexOf(PropertyUtils.MAPPED_DELIM2); 1464 if ((delim < 0) || (delim2 <= delim)) { 1465 throw new IllegalArgumentException 1466 ("Invalid mapped property '" + name + "'"); 1467 } 1468 1469 String key = name.substring(delim + 1, delim2); 1471 name = name.substring(0, delim); 1472 1473 setMappedProperty(bean, name, key, value); 1475 1476 } 1477 1478 1479 1495 public void setMappedProperty(Object bean, String name, 1496 String key, Object value) 1497 throws IllegalAccessException , InvocationTargetException , 1498 NoSuchMethodException { 1499 1500 if (bean == null) { 1501 throw new IllegalArgumentException ("No bean specified"); 1502 } 1503 if (name == null) { 1504 throw new IllegalArgumentException ("No name specified"); 1505 } 1506 if (key == null) { 1507 throw new IllegalArgumentException ("No key specified"); 1508 } 1509 1510 if (bean instanceof DynaBean) { 1512 DynaProperty descriptor = 1513 ((DynaBean) bean).getDynaClass().getDynaProperty(name); 1514 if (descriptor == null) { 1515 throw new NoSuchMethodException ("Unknown property '" + 1516 name + "'"); 1517 } 1518 ((DynaBean) bean).set(name, key, value); 1519 return; 1520 } 1521 1522 PropertyDescriptor descriptor = 1524 getPropertyDescriptor(bean, name); 1525 if (descriptor == null) { 1526 throw new NoSuchMethodException ("Unknown property '" + 1527 name + "'"); 1528 } 1529 1530 if (descriptor instanceof MappedPropertyDescriptor) { 1531 Method mappedWriteMethod = 1533 ((MappedPropertyDescriptor) descriptor). 1534 getMappedWriteMethod(); 1535 if (mappedWriteMethod != null) { 1536 Object params[] = new Object [2]; 1537 params[0] = key; 1538 params[1] = value; 1539 if (log.isTraceEnabled()) { 1540 String valueClassName = 1541 value == null ? "<null>" : value.getClass().getName(); 1542 log.trace("setSimpleProperty: Invoking method " 1543 + mappedWriteMethod + " with key=" + key 1544 + ", value=" + value 1545 + " (class " + valueClassName +")"); 1546 } 1547 invokeMethod(mappedWriteMethod, bean, params); 1548 } else { 1549 throw new NoSuchMethodException 1550 ("Property '" + name + 1551 "' has no mapped setter method"); 1552 } 1553 } else { 1554 1555 Method readMethod = descriptor.getReadMethod(); 1556 if (readMethod != null) { 1557 Object invokeResult = invokeMethod(readMethod, bean, new Object [0]); 1558 1559 if (invokeResult instanceof java.util.Map ) { 1560 ((java.util.Map )invokeResult).put(key, value); 1561 } 1562 } else { 1563 throw new NoSuchMethodException ("Property '" + name + 1564 "' has no mapped getter method"); 1565 } 1566 } 1567 1568 } 1569 1570 1571 1590 public void setNestedProperty(Object bean, 1591 String name, Object value) 1592 throws IllegalAccessException , InvocationTargetException , 1593 NoSuchMethodException { 1594 1595 if (bean == null) { 1596 throw new IllegalArgumentException ("No bean specified"); 1597 } 1598 if (name == null) { 1599 throw new IllegalArgumentException ("No name specified"); 1600 } 1601 1602 int indexOfINDEXED_DELIM = -1; 1603 int indexOfMAPPED_DELIM = -1; 1604 while (true) { 1605 int delim = name.indexOf(PropertyUtils.NESTED_DELIM); 1606 if (delim < 0) { 1607 break; 1608 } 1609 String next = name.substring(0, delim); 1610 indexOfINDEXED_DELIM = next.indexOf(PropertyUtils.INDEXED_DELIM); 1611 indexOfMAPPED_DELIM = next.indexOf(PropertyUtils.MAPPED_DELIM); 1612 if (bean instanceof Map ) { 1613 bean = ((Map ) bean).get(next); 1614 } else if (indexOfMAPPED_DELIM >= 0) { 1615 bean = getMappedProperty(bean, next); 1616 } else if (indexOfINDEXED_DELIM >= 0) { 1617 bean = getIndexedProperty(bean, next); 1618 } else { 1619 bean = getSimpleProperty(bean, next); 1620 } 1621 if (bean == null) { 1622 throw new IllegalArgumentException 1623 ("Null property value for '" + 1624 name.substring(0, delim) + "'"); 1625 } 1626 name = name.substring(delim + 1); 1627 } 1628 1629 indexOfINDEXED_DELIM = name.indexOf(PropertyUtils.INDEXED_DELIM); 1630 indexOfMAPPED_DELIM = name.indexOf(PropertyUtils.MAPPED_DELIM); 1631 1632 if (bean instanceof Map ) { 1633 PropertyDescriptor descriptor = 1635 getPropertyDescriptor(bean, name); 1636 if (descriptor == null) { 1637 ((Map ) bean).put(name, value); 1639 } else { 1640 setSimpleProperty(bean, name, value); 1642 } 1643 } else if (indexOfMAPPED_DELIM >= 0) { 1644 setMappedProperty(bean, name, value); 1645 } else if (indexOfINDEXED_DELIM >= 0) { 1646 setIndexedProperty(bean, name, value); 1647 } else { 1648 setSimpleProperty(bean, name, value); 1649 } 1650 1651 } 1652 1653 1654 1673 public void setProperty(Object bean, String name, Object value) 1674 throws IllegalAccessException , InvocationTargetException , 1675 NoSuchMethodException { 1676 1677 setNestedProperty(bean, name, value); 1678 1679 } 1680 1681 1682 1701 public void setSimpleProperty(Object bean, 1702 String name, Object value) 1703 throws IllegalAccessException , InvocationTargetException , 1704 NoSuchMethodException { 1705 1706 if (bean == null) { 1707 throw new IllegalArgumentException ("No bean specified"); 1708 } 1709 if (name == null) { 1710 throw new IllegalArgumentException ("No name specified"); 1711 } 1712 1713 if (name.indexOf(PropertyUtils.NESTED_DELIM) >= 0) { 1715 throw new IllegalArgumentException 1716 ("Nested property names are not allowed"); 1717 } else if (name.indexOf(PropertyUtils.INDEXED_DELIM) >= 0) { 1718 throw new IllegalArgumentException 1719 ("Indexed property names are not allowed"); 1720 } else if (name.indexOf(PropertyUtils.MAPPED_DELIM) >= 0) { 1721 throw new IllegalArgumentException 1722 ("Mapped property names are not allowed"); 1723 } 1724 1725 if (bean instanceof DynaBean) { 1727 DynaProperty descriptor = 1728 ((DynaBean) bean).getDynaClass().getDynaProperty(name); 1729 if (descriptor == null) { 1730 throw new NoSuchMethodException ("Unknown property '" + 1731 name + "'"); 1732 } 1733 ((DynaBean) bean).set(name, value); 1734 return; 1735 } 1736 1737 PropertyDescriptor descriptor = 1739 getPropertyDescriptor(bean, name); 1740 if (descriptor == null) { 1741 throw new NoSuchMethodException ("Unknown property '" + 1742 name + "'"); 1743 } 1744 Method writeMethod = getWriteMethod(descriptor); 1745 if (writeMethod == null) { 1746 throw new NoSuchMethodException ("Property '" + name + 1747 "' has no setter method"); 1748 } 1749 1750 Object values[] = new Object [1]; 1752 values[0] = value; 1753 if (log.isTraceEnabled()) { 1754 String valueClassName = 1755 value == null ? "<null>" : value.getClass().getName(); 1756 log.trace("setSimpleProperty: Invoking method " + writeMethod 1757 + " with value " + value + " (class " + valueClassName + ")"); 1758 } 1759 invokeMethod(writeMethod, bean, values); 1760 1761 } 1762 1763 1764 private Object invokeMethod( 1765 Method method, 1766 Object bean, 1767 Object [] values) 1768 throws 1769 IllegalAccessException , 1770 InvocationTargetException { 1771 try { 1772 1773 return method.invoke(bean, values); 1774 1775 } catch (IllegalArgumentException e) { 1776 1777 log.error("Method invocation failed.", e); 1778 throw new IllegalArgumentException ( 1779 "Cannot invoke " + method.getDeclaringClass().getName() + "." 1780 + method.getName() + " - " + e.getMessage()); 1781 1782 } 1783 } 1784} 1785 | Popular Tags |