1 61 62 package com.opensymphony.workflow.designer.beanutils; 63 64 import java.beans.*; 65 import java.lang.reflect.Array ; 66 import java.lang.reflect.InvocationTargetException ; 67 import java.lang.reflect.Method ; 68 import java.util.*; 69 70 127 128 public class PropertyUtilsBean 129 { 130 131 private static final PropertyUtilsBean instance = new PropertyUtilsBean(); 132 133 135 protected static PropertyUtilsBean getInstance() 136 { 137 return instance; 138 } 139 140 142 146 private Map descriptorsCache = null; 147 private Map mappedDescriptorsCache = null; 148 149 151 154 public PropertyUtilsBean() 155 { 156 descriptorsCache = new HashMap(); 157 mappedDescriptorsCache = new HashMap(); 158 } 159 160 161 163 164 169 public void clearDescriptors() 170 { 171 172 descriptorsCache.clear(); 173 mappedDescriptorsCache.clear(); 174 Introspector.flushCaches(); 175 176 } 177 178 205 public void copyProperties(Object dest, Object orig) throws IllegalAccessException , InvocationTargetException , NoSuchMethodException 206 { 207 208 if(dest == null) 209 { 210 throw new IllegalArgumentException ("No destination bean specified"); 211 } 212 if(orig == null) 213 { 214 throw new IllegalArgumentException ("No origin bean specified"); 215 } 216 if(orig instanceof Map) 217 { 218 Iterator names = ((Map)orig).keySet().iterator(); 219 while(names.hasNext()) 220 { 221 String name = (String )names.next(); 222 if(isWriteable(dest, name)) 223 { 224 Object value = ((Map)orig).get(name); 225 setSimpleProperty(dest, name, value); 226 } 227 } 228 } 229 else 230 { 231 PropertyDescriptor origDescriptors[] = getPropertyDescriptors(orig); 232 for(int i = 0; i < origDescriptors.length; i++) 233 { 234 String name = origDescriptors[i].getName(); 235 if(isReadable(orig, name)) 236 { 237 if(isWriteable(dest, name)) 238 { 239 Object value = getSimpleProperty(orig, name); 240 setSimpleProperty(dest, name, value); 241 } 242 } 243 } 244 } 245 246 } 247 248 265 public Map describe(Object bean) throws IllegalAccessException , InvocationTargetException , NoSuchMethodException 266 { 267 268 if(bean == null) 269 { 270 throw new IllegalArgumentException ("No bean specified"); 271 } 272 Map description = new HashMap(); 273 PropertyDescriptor descriptors[] = getPropertyDescriptors(bean); 274 for(int i = 0; i < descriptors.length; i++) 275 { 276 String name = descriptors[i].getName(); 277 if(descriptors[i].getReadMethod() != null) 278 description.put(name, getProperty(bean, name)); 279 } 280 return (description); 281 282 } 283 284 306 public Object getIndexedProperty(Object bean, String name) throws IllegalAccessException , InvocationTargetException , NoSuchMethodException 307 { 308 309 if(bean == null) 310 { 311 throw new IllegalArgumentException ("No bean specified"); 312 } 313 if(name == null) 314 { 315 throw new IllegalArgumentException ("No name specified"); 316 } 317 318 int delim = name.indexOf(PropertyUtils.INDEXED_DELIM); 320 int delim2 = name.indexOf(PropertyUtils.INDEXED_DELIM2); 321 if((delim < 0) || (delim2 <= delim)) 322 { 323 throw new IllegalArgumentException ("Invalid indexed property '" + name + "'"); 324 } 325 int index = -1; 326 try 327 { 328 String subscript = name.substring(delim + 1, delim2); 329 index = Integer.parseInt(subscript); 330 } 331 catch(NumberFormatException e) 332 { 333 throw new IllegalArgumentException ("Invalid indexed property '" + name + "'"); 334 } 335 name = name.substring(0, delim); 336 337 return (getIndexedProperty(bean, name, index)); 339 340 } 341 342 362 public Object getIndexedProperty(Object bean, String name, int index) throws IllegalAccessException , InvocationTargetException , NoSuchMethodException 363 { 364 365 if(bean == null) 366 { 367 throw new IllegalArgumentException ("No bean specified"); 368 } 369 if(name == null) 370 { 371 throw new IllegalArgumentException ("No name specified"); 372 } 373 374 PropertyDescriptor descriptor = getPropertyDescriptor(bean, name); 376 if(descriptor == null) 377 { 378 throw new NoSuchMethodException ("Unknown property '" + name + "'"); 379 } 380 381 if(descriptor instanceof IndexedPropertyDescriptor) 383 { 384 Method readMethod = ((IndexedPropertyDescriptor)descriptor).getIndexedReadMethod(); 385 if(readMethod != null) 386 { 387 Object subscript[] = new Object [1]; 388 subscript[0] = new Integer (index); 389 try 390 { 391 return (invokeMethod(readMethod, bean, subscript)); 392 } 393 catch(InvocationTargetException e) 394 { 395 if(e.getTargetException() instanceof ArrayIndexOutOfBoundsException ) 396 { 397 throw (ArrayIndexOutOfBoundsException )e.getTargetException(); 398 } 399 else 400 { 401 throw e; 402 } 403 } 404 } 405 } 406 407 Method readMethod = getReadMethod(descriptor); 409 if(readMethod == null) 410 { 411 throw new NoSuchMethodException ("Property '" + name + "' has no getter method"); 412 } 413 414 Object value = invokeMethod(readMethod, bean, new Object [0]); 416 if(!value.getClass().isArray()) 417 { 418 if(!(value instanceof java.util.List )) 419 { 420 throw new IllegalArgumentException ("Property '" + name + "' is not indexed"); 421 } 422 else 423 { 424 return ((java.util.List )value).get(index); 426 } 427 } 428 else 429 { 430 return (Array.get(value, index)); 432 } 433 434 } 435 436 453 public Object getMappedProperty(Object bean, String name) throws IllegalAccessException , InvocationTargetException , NoSuchMethodException 454 { 455 456 if(bean == null) 457 { 458 throw new IllegalArgumentException ("No bean specified"); 459 } 460 if(name == null) 461 { 462 throw new IllegalArgumentException ("No name specified"); 463 } 464 465 int delim = name.indexOf(PropertyUtils.MAPPED_DELIM); 467 int delim2 = name.indexOf(PropertyUtils.MAPPED_DELIM2); 468 if((delim < 0) || (delim2 <= delim)) 469 { 470 throw new IllegalArgumentException ("Invalid mapped property '" + name + "'"); 471 } 472 473 String key = name.substring(delim + 1, delim2); 475 name = name.substring(0, delim); 476 477 return (getMappedProperty(bean, name, key)); 479 480 } 481 482 496 public Object getMappedProperty(Object bean, String name, String key) throws IllegalAccessException , InvocationTargetException , NoSuchMethodException 497 { 498 499 if(bean == null) 500 { 501 throw new IllegalArgumentException ("No bean specified"); 502 } 503 if(name == null) 504 { 505 throw new IllegalArgumentException ("No name specified"); 506 } 507 if(key == null) 508 { 509 throw new IllegalArgumentException ("No key specified"); 510 } 511 512 Object result = null; 514 515 PropertyDescriptor descriptor = getPropertyDescriptor(bean, name); 517 if(descriptor == null) 518 { 519 throw new NoSuchMethodException ("Unknown property '" + name + "'"); 520 } 521 522 if(descriptor instanceof MappedPropertyDescriptor) 523 { 524 Method readMethod = ((MappedPropertyDescriptor)descriptor).getMappedReadMethod(); 526 if(readMethod != null) 527 { 528 Object keyArray[] = new Object [1]; 529 keyArray[0] = key; 530 result = invokeMethod(readMethod, bean, keyArray); 531 } 532 else 533 { 534 throw new NoSuchMethodException ("Property '" + name + "' has no mapped getter method"); 535 } 536 } 537 else 538 { 539 540 Method readMethod = descriptor.getReadMethod(); 541 if(readMethod != null) 542 { 543 Object invokeResult = invokeMethod(readMethod, bean, new Object [0]); 544 545 if(invokeResult instanceof java.util.Map ) 546 { 547 result = ((java.util.Map )invokeResult).get(key); 548 } 549 } 550 else 551 { 552 throw new NoSuchMethodException ("Property '" + name + "' has no mapped getter method"); 553 } 554 } 555 return result; 556 557 } 558 559 566 public Map getMappedPropertyDescriptors(Class beanClass) 567 { 568 569 if(beanClass == null) 570 { 571 return null; 572 } 573 574 return (Map)mappedDescriptorsCache.get(beanClass); 576 577 } 578 579 586 public Map getMappedPropertyDescriptors(Object bean) 587 { 588 589 if(bean == null) 590 { 591 return null; 592 } 593 return (getMappedPropertyDescriptors(bean.getClass())); 594 595 } 596 597 613 public Object getNestedProperty(Object bean, String name) throws IllegalAccessException , InvocationTargetException , NoSuchMethodException 614 { 615 616 if(bean == null) 617 { 618 throw new IllegalArgumentException ("No bean specified"); 619 } 620 if(name == null) 621 { 622 throw new IllegalArgumentException ("No name specified"); 623 } 624 625 int indexOfINDEXED_DELIM = -1; 626 int indexOfMAPPED_DELIM = -1; 627 int indexOfMAPPED_DELIM2 = -1; 628 int indexOfNESTED_DELIM = -1; 629 while(true) 630 { 631 indexOfNESTED_DELIM = name.indexOf(PropertyUtils.NESTED_DELIM); 632 indexOfMAPPED_DELIM = name.indexOf(PropertyUtils.MAPPED_DELIM); 633 indexOfMAPPED_DELIM2 = name.indexOf(PropertyUtils.MAPPED_DELIM2); 634 if(indexOfMAPPED_DELIM2 >= 0 && indexOfMAPPED_DELIM >= 0 && (indexOfNESTED_DELIM < 0 || indexOfNESTED_DELIM > indexOfMAPPED_DELIM)) 635 { 636 indexOfNESTED_DELIM = name.indexOf(PropertyUtils.NESTED_DELIM, indexOfMAPPED_DELIM2); 637 } 638 else 639 { 640 indexOfNESTED_DELIM = name.indexOf(PropertyUtils.NESTED_DELIM); 641 } 642 if(indexOfNESTED_DELIM < 0) 643 { 644 break; 645 } 646 String next = name.substring(0, indexOfNESTED_DELIM); 647 indexOfINDEXED_DELIM = next.indexOf(PropertyUtils.INDEXED_DELIM); 648 indexOfMAPPED_DELIM = next.indexOf(PropertyUtils.MAPPED_DELIM); 649 if(bean instanceof Map) 650 { 651 bean = ((Map)bean).get(next); 652 } 653 else if(indexOfMAPPED_DELIM >= 0) 654 { 655 bean = getMappedProperty(bean, next); 656 } 657 else if(indexOfINDEXED_DELIM >= 0) 658 { 659 bean = getIndexedProperty(bean, next); 660 } 661 else 662 { 663 bean = getSimpleProperty(bean, next); 664 } 665 if(bean == null) 666 { 667 throw new NullPointerException ("Null property value for '" + name.substring(0, indexOfNESTED_DELIM) + "'"); 668 } 669 name = name.substring(indexOfNESTED_DELIM + 1); 670 } 671 672 indexOfINDEXED_DELIM = name.indexOf(PropertyUtils.INDEXED_DELIM); 673 indexOfMAPPED_DELIM = name.indexOf(PropertyUtils.MAPPED_DELIM); 674 675 if(bean instanceof Map) 676 { 677 bean = ((Map)bean).get(name); 678 } 679 else if(indexOfMAPPED_DELIM >= 0) 680 { 681 bean = getMappedProperty(bean, name); 682 } 683 else if(indexOfINDEXED_DELIM >= 0) 684 { 685 bean = getIndexedProperty(bean, name); 686 } 687 else 688 { 689 bean = getSimpleProperty(bean, name); 690 } 691 return bean; 692 693 } 694 695 712 public Object getProperty(Object bean, String name) throws IllegalAccessException , InvocationTargetException , NoSuchMethodException 713 { 714 715 return (getNestedProperty(bean, name)); 716 717 } 718 719 743 public PropertyDescriptor getPropertyDescriptor(Object bean, String name) throws IllegalAccessException , InvocationTargetException , NoSuchMethodException 744 { 745 746 if(bean == null) 747 { 748 throw new IllegalArgumentException ("No bean specified"); 749 } 750 if(name == null) 751 { 752 throw new IllegalArgumentException ("No name specified"); 753 } 754 755 while(true) 757 { 758 int period = findNextNestedIndex(name); 759 if(period < 0) 760 { 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 && (indexOfINDEXED_DELIM < 0 || indexOfMAPPED_DELIM < indexOfINDEXED_DELIM)) 767 { 768 bean = getMappedProperty(bean, next); 769 } 770 else 771 { 772 if(indexOfINDEXED_DELIM >= 0) 773 { 774 bean = getIndexedProperty(bean, next); 775 } 776 else 777 { 778 bean = getSimpleProperty(bean, next); 779 } 780 } 781 if(bean == null) 782 { 783 throw new IllegalArgumentException ("Null property value for '" + name.substring(0, period) + "'"); 784 } 785 name = name.substring(period + 1); 786 } 787 788 int left = name.indexOf(PropertyUtils.INDEXED_DELIM); 790 if(left >= 0) 791 { 792 name = name.substring(0, left); 793 } 794 left = name.indexOf(PropertyUtils.MAPPED_DELIM); 795 if(left >= 0) 796 { 797 name = name.substring(0, left); 798 } 799 800 if((bean == null) || (name == null)) 803 { 804 return (null); 805 } 806 807 PropertyDescriptor descriptors[] = getPropertyDescriptors(bean); 808 if(descriptors != null) 809 { 810 811 for(int i = 0; i < descriptors.length; i++) 812 { 813 if(name.equals(descriptors[i].getName())) 814 return (descriptors[i]); 815 } 816 } 817 818 PropertyDescriptor result = null; 819 Map mappedDescriptors = getMappedPropertyDescriptors(bean); 820 if(mappedDescriptors == null) 821 { 822 mappedDescriptors = new HashMap(); 823 mappedDescriptorsCache.put(bean.getClass(), mappedDescriptors); 824 } 825 result = (PropertyDescriptor)mappedDescriptors.get(name); 826 if(result == null) 827 { 828 try 830 { 831 result = new MappedPropertyDescriptor(name, bean.getClass()); 832 } 833 catch(IntrospectionException ie) 834 { 835 } 836 if(result != null) 837 { 838 mappedDescriptors.put(name, result); 839 } 840 } 841 842 return result; 843 844 } 845 846 private int findNextNestedIndex(String expression) 847 { 848 int bracketCount = 0; 851 for(int i = 0, size = expression.length(); i < size; i++) 852 { 853 char at = expression.charAt(i); 854 switch(at) 855 { 856 case PropertyUtils.NESTED_DELIM: 857 if(bracketCount < 1) 858 { 859 return i; 860 } 861 break; 862 863 case PropertyUtils.MAPPED_DELIM: 864 case PropertyUtils.INDEXED_DELIM: 865 ++bracketCount; 867 break; 868 869 case PropertyUtils.MAPPED_DELIM2: 870 case PropertyUtils.INDEXED_DELIM2: 871 --bracketCount; 873 break; 874 } 875 } 876 return -1; 878 } 879 880 890 public PropertyDescriptor[] getPropertyDescriptors(Class beanClass) 891 { 892 893 if(beanClass == null) 894 { 895 throw new IllegalArgumentException ("No bean class specified"); 896 } 897 898 PropertyDescriptor descriptors[] = null; 900 descriptors = (PropertyDescriptor[])descriptorsCache.get(beanClass); 901 if(descriptors != null) 902 { 903 return (descriptors); 904 } 905 906 BeanInfo beanInfo = null; 908 try 909 { 910 beanInfo = Introspector.getBeanInfo(beanClass); 911 } 912 catch(IntrospectionException e) 913 { 914 return (new PropertyDescriptor[0]); 915 } 916 descriptors = beanInfo.getPropertyDescriptors(); 917 if(descriptors == null) 918 { 919 descriptors = new PropertyDescriptor[0]; 920 } 921 descriptorsCache.put(beanClass, descriptors); 922 return (descriptors); 923 924 } 925 926 936 public PropertyDescriptor[] getPropertyDescriptors(Object bean) 937 { 938 939 if(bean == null) 940 { 941 throw new IllegalArgumentException ("No bean specified"); 942 } 943 return (getPropertyDescriptors(bean.getClass())); 944 945 } 946 947 975 public Class getPropertyEditorClass(Object bean, String name) throws IllegalAccessException , InvocationTargetException , NoSuchMethodException 976 { 977 978 if(bean == null) 979 { 980 throw new IllegalArgumentException ("No bean specified"); 981 } 982 if(name == null) 983 { 984 throw new IllegalArgumentException ("No name specified"); 985 } 986 987 PropertyDescriptor descriptor = getPropertyDescriptor(bean, name); 988 if(descriptor != null) 989 { 990 return (descriptor.getPropertyEditorClass()); 991 } 992 else 993 { 994 return (null); 995 } 996 997 } 998 999 1022 public Class getPropertyType(Object bean, String name) throws IllegalAccessException , InvocationTargetException , NoSuchMethodException 1023 { 1024 1025 if(bean == null) 1026 { 1027 throw new IllegalArgumentException ("No bean specified"); 1028 } 1029 if(name == null) 1030 { 1031 throw new IllegalArgumentException ("No name specified"); 1032 } 1033 1034 PropertyDescriptor descriptor = getPropertyDescriptor(bean, name); 1035 if(descriptor == null) 1036 { 1037 return (null); 1038 } 1039 else if(descriptor instanceof IndexedPropertyDescriptor) 1040 { 1041 return (((IndexedPropertyDescriptor)descriptor).getIndexedPropertyType()); 1042 } 1043 else if(descriptor instanceof MappedPropertyDescriptor) 1044 { 1045 return (((MappedPropertyDescriptor)descriptor).getMappedPropertyType()); 1046 } 1047 else 1048 { 1049 return (descriptor.getPropertyType()); 1050 } 1051 1052 } 1053 1054 1062 public Method getReadMethod(PropertyDescriptor descriptor) 1063 { 1064 1065 return (MethodUtils.getAccessibleMethod(descriptor.getReadMethod())); 1066 1067 } 1068 1069 1086 public Object getSimpleProperty(Object bean, String name) throws IllegalAccessException , InvocationTargetException , NoSuchMethodException 1087 { 1088 1089 if(bean == null) 1090 { 1091 throw new IllegalArgumentException ("No bean specified"); 1092 } 1093 if(name == null) 1094 { 1095 throw new IllegalArgumentException ("No name specified"); 1096 } 1097 1098 if(name.indexOf(PropertyUtils.NESTED_DELIM) >= 0) 1100 { 1101 throw new IllegalArgumentException ("Nested property names are not allowed"); 1102 } 1103 else if(name.indexOf(PropertyUtils.INDEXED_DELIM) >= 0) 1104 { 1105 throw new IllegalArgumentException ("Indexed property names are not allowed"); 1106 } 1107 else if(name.indexOf(PropertyUtils.MAPPED_DELIM) >= 0) 1108 { 1109 throw new IllegalArgumentException ("Mapped property names are not allowed"); 1110 } 1111 1112 PropertyDescriptor descriptor = getPropertyDescriptor(bean, name); 1114 if(descriptor == null) 1115 { 1116 throw new NoSuchMethodException ("Unknown property '" + name + "'"); 1117 } 1118 Method readMethod = getReadMethod(descriptor); 1119 if(readMethod == null) 1120 { 1121 throw new NoSuchMethodException ("Property '" + name + "' has no getter method"); 1122 } 1123 1124 Object value = invokeMethod(readMethod, bean, new Object [0]); 1126 return (value); 1127 1128 } 1129 1130 1138 public Method getWriteMethod(PropertyDescriptor descriptor) 1139 { 1140 1141 return (MethodUtils.getAccessibleMethod(descriptor.getWriteMethod())); 1142 1143 } 1144 1145 1156 public boolean isReadable(Object bean, String name) 1157 { 1158 1159 if(bean == null) 1161 { 1162 throw new IllegalArgumentException ("No bean specified"); 1163 } 1164 if(name == null) 1165 { 1166 throw new IllegalArgumentException ("No name specified"); 1167 } 1168 1169 try 1171 { 1172 PropertyDescriptor desc = getPropertyDescriptor(bean, name); 1173 if(desc != null) 1174 { 1175 Method readMethod = desc.getReadMethod(); 1176 if((readMethod == null) && (desc instanceof IndexedPropertyDescriptor)) 1177 { 1178 readMethod = ((IndexedPropertyDescriptor)desc).getIndexedReadMethod(); 1179 } 1180 return (readMethod != null); 1181 } 1182 else 1183 { 1184 return (false); 1185 } 1186 } 1187 catch(IllegalAccessException e) 1188 { 1189 return (false); 1190 } 1191 catch(InvocationTargetException e) 1192 { 1193 return (false); 1194 } 1195 catch(NoSuchMethodException e) 1196 { 1197 return (false); 1198 } 1199 1200 } 1201 1202 1213 public boolean isWriteable(Object bean, String name) 1214 { 1215 1216 if(bean == null) 1218 { 1219 throw new IllegalArgumentException ("No bean specified"); 1220 } 1221 if(name == null) 1222 { 1223 throw new IllegalArgumentException ("No name specified"); 1224 } 1225 1226 try 1228 { 1229 PropertyDescriptor desc = getPropertyDescriptor(bean, name); 1230 if(desc != null) 1231 { 1232 Method writeMethod = desc.getWriteMethod(); 1233 if((writeMethod == null) && (desc instanceof IndexedPropertyDescriptor)) 1234 { 1235 writeMethod = ((IndexedPropertyDescriptor)desc).getIndexedWriteMethod(); 1236 } 1237 return (writeMethod != null); 1238 } 1239 else 1240 { 1241 return (false); 1242 } 1243 } 1244 catch(IllegalAccessException e) 1245 { 1246 return (false); 1247 } 1248 catch(InvocationTargetException e) 1249 { 1250 return (false); 1251 } 1252 catch(NoSuchMethodException e) 1253 { 1254 return (false); 1255 } 1256 } 1257 1258 1282 public void setIndexedProperty(Object bean, String name, Object value) throws IllegalAccessException , InvocationTargetException , NoSuchMethodException 1283 { 1284 1285 if(bean == null) 1286 { 1287 throw new IllegalArgumentException ("No bean specified"); 1288 } 1289 if(name == null) 1290 { 1291 throw new IllegalArgumentException ("No name specified"); 1292 } 1293 1294 int delim = name.indexOf(PropertyUtils.INDEXED_DELIM); 1296 int delim2 = name.indexOf(PropertyUtils.INDEXED_DELIM2); 1297 if((delim < 0) || (delim2 <= delim)) 1298 { 1299 throw new IllegalArgumentException ("Invalid indexed property '" + name + "'"); 1300 } 1301 int index = -1; 1302 try 1303 { 1304 String subscript = name.substring(delim + 1, delim2); 1305 index = Integer.parseInt(subscript); 1306 } 1307 catch(NumberFormatException e) 1308 { 1309 throw new IllegalArgumentException ("Invalid indexed property '" + name + "'"); 1310 } 1311 name = name.substring(0, delim); 1312 1313 setIndexedProperty(bean, name, index, value); 1315 1316 } 1317 1318 1339 public void setIndexedProperty(Object bean, String name, int index, Object value) throws IllegalAccessException , InvocationTargetException , NoSuchMethodException 1340 { 1341 1342 if(bean == null) 1343 { 1344 throw new IllegalArgumentException ("No bean specified"); 1345 } 1346 if(name == null) 1347 { 1348 throw new IllegalArgumentException ("No name specified"); 1349 } 1350 1351 PropertyDescriptor descriptor = getPropertyDescriptor(bean, name); 1353 if(descriptor == null) 1354 { 1355 throw new NoSuchMethodException ("Unknown property '" + name + "'"); 1356 } 1357 1358 if(descriptor instanceof IndexedPropertyDescriptor) 1360 { 1361 Method writeMethod = ((IndexedPropertyDescriptor)descriptor).getIndexedWriteMethod(); 1362 if(writeMethod != null) 1363 { 1364 Object subscript[] = new Object [2]; 1365 subscript[0] = new Integer (index); 1366 subscript[1] = value; 1367 try 1368 { 1369 invokeMethod(writeMethod, bean, subscript); 1370 } 1371 catch(InvocationTargetException e) 1372 { 1373 if(e.getTargetException() instanceof ArrayIndexOutOfBoundsException ) 1374 { 1375 throw (ArrayIndexOutOfBoundsException )e.getTargetException(); 1376 } 1377 else 1378 { 1379 throw e; 1380 } 1381 } 1382 return; 1383 } 1384 } 1385 1386 Method readMethod = descriptor.getReadMethod(); 1388 if(readMethod == null) 1389 { 1390 throw new NoSuchMethodException ("Property '" + name + "' has no getter method"); 1391 } 1392 1393 Object array = invokeMethod(readMethod, bean, new Object [0]); 1395 if(!array.getClass().isArray()) 1396 { 1397 if(array instanceof List) 1398 { 1399 ((List)array).set(index, value); 1401 } 1402 else 1403 { 1404 throw new IllegalArgumentException ("Property '" + name + "' is not indexed"); 1405 } 1406 } 1407 else 1408 { 1409 Array.set(array, index, value); 1411 } 1412 1413 } 1414 1415 1433 public void setMappedProperty(Object bean, String name, Object value) throws IllegalAccessException , InvocationTargetException , NoSuchMethodException 1434 { 1435 1436 if(bean == null) 1437 { 1438 throw new IllegalArgumentException ("No bean specified"); 1439 } 1440 if(name == null) 1441 { 1442 throw new IllegalArgumentException ("No name specified"); 1443 } 1444 1445 int delim = name.indexOf(PropertyUtils.MAPPED_DELIM); 1447 int delim2 = name.indexOf(PropertyUtils.MAPPED_DELIM2); 1448 if((delim < 0) || (delim2 <= delim)) 1449 { 1450 throw new IllegalArgumentException ("Invalid mapped property '" + name + "'"); 1451 } 1452 1453 String key = name.substring(delim + 1, delim2); 1455 name = name.substring(0, delim); 1456 1457 setMappedProperty(bean, name, key, value); 1459 1460 } 1461 1462 1477 public void setMappedProperty(Object bean, String name, String key, Object value) throws IllegalAccessException , InvocationTargetException , NoSuchMethodException 1478 { 1479 1480 if(bean == null) 1481 { 1482 throw new IllegalArgumentException ("No bean specified"); 1483 } 1484 if(name == null) 1485 { 1486 throw new IllegalArgumentException ("No name specified"); 1487 } 1488 if(key == null) 1489 { 1490 throw new IllegalArgumentException ("No key specified"); 1491 } 1492 1493 PropertyDescriptor descriptor = getPropertyDescriptor(bean, name); 1495 if(descriptor == null) 1496 { 1497 throw new NoSuchMethodException ("Unknown property '" + name + "'"); 1498 } 1499 1500 if(descriptor instanceof MappedPropertyDescriptor) 1501 { 1502 Method mappedWriteMethod = ((MappedPropertyDescriptor)descriptor).getMappedWriteMethod(); 1504 if(mappedWriteMethod != null) 1505 { 1506 Object params[] = new Object [2]; 1507 params[0] = key; 1508 params[1] = value; 1509 invokeMethod(mappedWriteMethod, bean, params); 1510 } 1511 else 1512 { 1513 throw new NoSuchMethodException ("Property '" + name + "' has no mapped setter method"); 1514 } 1515 } 1516 else 1517 { 1518 1519 Method readMethod = descriptor.getReadMethod(); 1520 if(readMethod != null) 1521 { 1522 Object invokeResult = invokeMethod(readMethod, bean, new Object [0]); 1523 1524 if(invokeResult instanceof java.util.Map ) 1525 { 1526 ((java.util.Map )invokeResult).put(key, value); 1527 } 1528 } 1529 else 1530 { 1531 throw new NoSuchMethodException ("Property '" + name + "' has no mapped getter method"); 1532 } 1533 } 1534 1535 } 1536 1537 1555 public void setNestedProperty(Object bean, String name, Object value) throws IllegalAccessException , InvocationTargetException , NoSuchMethodException 1556 { 1557 1558 if(bean == null) 1559 { 1560 throw new IllegalArgumentException ("No bean specified"); 1561 } 1562 if(name == null) 1563 { 1564 throw new IllegalArgumentException ("No name specified"); 1565 } 1566 1567 int indexOfINDEXED_DELIM = -1; 1568 int indexOfMAPPED_DELIM = -1; 1569 while(true) 1570 { 1571 int delim = name.indexOf(PropertyUtils.NESTED_DELIM); 1572 if(delim < 0) 1573 { 1574 break; 1575 } 1576 String next = name.substring(0, delim); 1577 indexOfINDEXED_DELIM = next.indexOf(PropertyUtils.INDEXED_DELIM); 1578 indexOfMAPPED_DELIM = next.indexOf(PropertyUtils.MAPPED_DELIM); 1579 if(bean instanceof Map) 1580 { 1581 bean = ((Map)bean).get(next); 1582 } 1583 else if(indexOfMAPPED_DELIM >= 0) 1584 { 1585 bean = getMappedProperty(bean, next); 1586 } 1587 else if(indexOfINDEXED_DELIM >= 0) 1588 { 1589 bean = getIndexedProperty(bean, next); 1590 } 1591 else 1592 { 1593 bean = getSimpleProperty(bean, next); 1594 } 1595 if(bean == null) 1596 { 1597 throw new IllegalArgumentException ("Null property value for '" + name.substring(0, delim) + "'"); 1598 } 1599 name = name.substring(delim + 1); 1600 } 1601 1602 indexOfINDEXED_DELIM = name.indexOf(PropertyUtils.INDEXED_DELIM); 1603 indexOfMAPPED_DELIM = name.indexOf(PropertyUtils.MAPPED_DELIM); 1604 1605 if(bean instanceof Map) 1606 { 1607 PropertyDescriptor descriptor = getPropertyDescriptor(bean, name); 1609 if(descriptor == null) 1610 { 1611 ((Map)bean).put(name, value); 1613 } 1614 else 1615 { 1616 setSimpleProperty(bean, name, value); 1618 } 1619 } 1620 else if(indexOfMAPPED_DELIM >= 0) 1621 { 1622 setMappedProperty(bean, name, value); 1623 } 1624 else if(indexOfINDEXED_DELIM >= 0) 1625 { 1626 setIndexedProperty(bean, name, value); 1627 } 1628 else 1629 { 1630 setSimpleProperty(bean, name, value); 1631 } 1632 1633 } 1634 1635 1653 public void setProperty(Object bean, String name, Object value) throws IllegalAccessException , InvocationTargetException , NoSuchMethodException 1654 { 1655 1656 setNestedProperty(bean, name, value); 1657 1658 } 1659 1660 1678 public void setSimpleProperty(Object bean, String name, Object value) throws IllegalAccessException , InvocationTargetException , NoSuchMethodException 1679 { 1680 1681 if(bean == null) 1682 { 1683 throw new IllegalArgumentException ("No bean specified"); 1684 } 1685 if(name == null) 1686 { 1687 throw new IllegalArgumentException ("No name specified"); 1688 } 1689 1690 if(name.indexOf(PropertyUtils.NESTED_DELIM) >= 0) 1692 { 1693 throw new IllegalArgumentException ("Nested property names are not allowed"); 1694 } 1695 else if(name.indexOf(PropertyUtils.INDEXED_DELIM) >= 0) 1696 { 1697 throw new IllegalArgumentException ("Indexed property names are not allowed"); 1698 } 1699 else if(name.indexOf(PropertyUtils.MAPPED_DELIM) >= 0) 1700 { 1701 throw new IllegalArgumentException ("Mapped property names are not allowed"); 1702 } 1703 1704 PropertyDescriptor descriptor = getPropertyDescriptor(bean, name); 1706 if(descriptor == null) 1707 { 1708 throw new NoSuchMethodException ("Unknown property '" + name + "'"); 1709 } 1710 Method writeMethod = getWriteMethod(descriptor); 1711 if(writeMethod == null) 1712 { 1713 throw new NoSuchMethodException ("Property '" + name + "' has no setter method"); 1714 } 1715 1716 Object values[] = new Object [1]; 1718 values[0] = value; 1719 invokeMethod(writeMethod, bean, values); 1720 1721 } 1722 1723 1726 private Object invokeMethod(Method method, Object bean, Object [] values) throws IllegalAccessException , InvocationTargetException 1727 { 1728 try 1729 { 1730 return method.invoke(bean, values); 1731 } 1732 catch(IllegalArgumentException e) 1733 { 1734 throw new IllegalArgumentException ("Cannot invoke " + method.getDeclaringClass().getName() + "." + method.getName() + " - " + e.getMessage()); 1735 } 1736 } 1737} 1738 | Popular Tags |