1 18 19 package org.objectweb.jac.core.rtti; 20 21 import gnu.regexp.RE; 22 import java.lang.reflect.InvocationTargetException ; 23 import java.lang.reflect.Modifier ; 24 import java.util.Collection ; 25 import java.util.Hashtable ; 26 import java.util.Iterator ; 27 import java.util.List ; 28 import java.util.Vector ; 29 import org.apache.log4j.Logger; 30 import java.lang.reflect.Constructor ; 31 32 39 40 public class ClassItem extends MetaItemDelegate { 41 42 static Logger logger = Logger.getLogger("rtti.class"); 43 44 static Class wrappeeClass = ClassRepository.wrappeeClass; 45 46 52 public ClassItem(Class delegate) throws InvalidDelegateException { 53 super(delegate); 54 Class superClass = delegate.getSuperclass(); 55 if (superClass!=Object .class && superClass!=null) { 56 try { 57 setSuperClass(ClassRepository.get().getClass(superClass)); 58 } catch(Exception e) { 59 logger.error("ClassItem("+delegate.getName()+"): "+e); 60 } 61 } 62 } 63 64 private int collsCount = 0; 65 private int refsCount = 0; 66 private int primsCount = 0; 67 private int methodsCount = 0; 68 private int constructorsCount = 0; 69 70 72 73 protected Hashtable fields = new Hashtable (); 74 75 77 78 protected Hashtable methods = new Hashtable (); 79 80 boolean rttiBuilt = false; 81 82 protected void buildFieldInfo() { 83 if (!rttiBuilt) { 84 rttiBuilt = true; 85 ClassRepository.get().buildDefaultFieldRTTI(this); 86 } 87 } 88 89 99 public FieldItem getField(String name) { 100 buildFieldInfo(); 101 FieldItem ret = getFieldNoError(name); 102 if (ret==null) { 103 throw new NoSuchFieldException (this,name); 104 } 105 return ret; 106 } 107 108 117 public FieldItem getFieldNoError(String name) { 118 buildFieldInfo(); 119 FieldItem field = (FieldItem)fields.get(name); 120 if (field==null) { 121 if (name.indexOf('.')!=-1) { 122 try { 123 List path = parseExpression(name); 124 if (path.get(path.size()-1) instanceof CollectionItem) { 125 field = new CollectionItem(name,path,this); 126 } else { 127 field = new FieldItem(name,path,this); 128 } 129 addField(field); 130 } catch (Exception e) { 131 field = null; 132 logger.error("Expression field "+this.getName()+"."+name+ 133 " instanciation failed: "+e); 134 e.printStackTrace(); 135 } 136 } 137 } 138 if (field==null && superClass!=null) { 139 field = superClass.getFieldNoError(name); 140 if (field!=null) { 141 field = field.clone(this); 142 addField(field); 143 } 144 } 145 return field; 146 } 147 148 152 public List parseExpression(String expression) { 153 Vector path = new Vector (); 154 String current = expression; 155 ClassItem curClass = this; 156 int dot = current.indexOf('.'); 157 FieldItem field = null; 158 while (dot!=-1) { 159 String fieldName = current.substring(0,dot); 160 field = curClass.getField(fieldName); 161 path.add(field); 162 if (field instanceof CollectionItem) 163 curClass = ((CollectionItem)field).getComponentType(); 164 else 165 curClass = field.getTypeItem(); 166 current = current.substring(dot+1); 167 dot = current.indexOf('.'); 168 } 169 170 field = curClass.getField(current); 171 path.add(field); 172 173 179 180 return path; 181 } 182 183 189 190 public CollectionItem getCollection(String name) { 191 buildFieldInfo(); 192 return (CollectionItem) fields.get(name); 193 } 194 195 200 201 public FieldItem[] getFields() { 202 buildFieldInfo(); 203 Collection c = fields.values(); 204 FieldItem[] res = new FieldItem[c.size()]; 205 Iterator it = c.iterator(); 206 int i = 0; 207 while (it.hasNext()) { 208 res[i] = (FieldItem) it.next(); 209 i++; 210 } 211 return res; 212 } 213 214 219 220 public Collection getAllFields() { 221 buildFieldInfo(); 222 return fields.values(); 223 } 224 225 234 public Collection getTaggedFields(String attribute, boolean not) { 235 buildFieldInfo(); 236 Collection c = fields.values(); 237 Iterator it = c.iterator(); 238 Vector result = new Vector (); 239 int i = 0; 240 while (it.hasNext()) { 241 FieldItem field = (FieldItem) it.next(); 242 if (field.getAttribute(attribute)!=null ^ not) { 243 result.add(field); 244 } 245 } 246 return result; 247 } 248 249 252 public Collection filterFields(String expression) { 253 logger.debug(this+".filterFields "+expression); 254 String keyword; 255 boolean not = false; 256 if (expression.charAt(0)=='!') { 257 not = true; 258 expression = expression.substring(1,expression.length()); 259 } 260 int filter = 0; 261 if (expression.equals("static")) 262 filter = Modifier.STATIC; 263 else if (expression.equals("public")) 264 filter = Modifier.PUBLIC; 265 else if (expression.equals("transient")) 266 filter = Modifier.TRANSIENT; 267 else if (expression.equals("private")) 268 filter = Modifier.PRIVATE; 269 else if (expression.equals("protected")) 270 filter = Modifier.PROTECTED; 271 Vector result = new Vector (); 272 Iterator it = fields.values().iterator(); 273 while (it.hasNext()) { 274 FieldItem field = (FieldItem) it.next(); 275 if (((field.getModifiers() & filter) != 0) ^ not) { 276 result.add(field); 277 } 278 } 279 logger.debug(" -> "+result); 280 return result; 281 } 282 283 public Collection getTaggedMethods(String attribute, boolean not) { 284 Collection c = getAllMethods(); 285 Iterator it = c.iterator(); 286 Vector result = new Vector (); 287 int i = 0; 288 while (it.hasNext()) { 289 AbstractMethodItem method = (AbstractMethodItem) it.next(); 290 if (method.getAttribute(attribute)!=null ^ not) { 291 result.add(method); 292 } 293 } 294 return result; 295 } 296 297 public Collection getTaggedMembers(String attribute, boolean not) { 298 Collection result = getTaggedMethods(attribute,not); 299 result.addAll(getTaggedFields(attribute,not)); 300 return result; 301 } 302 303 309 310 public Collection getTaggedMembers(String attribute, Object value) { 311 Collection result = getAllMembers(); 312 Collection result2 = new Vector (); 313 Iterator it = result.iterator(); 314 while (it.hasNext()) { 315 MemberItem member = (MemberItem)it.next(); 316 if (member.getAttribute(attribute)!=null 317 && value.equals(member.getAttribute(attribute))) 318 { 319 result2.add(member); 320 } 321 } 322 return result2; 323 } 324 325 331 public MemberItem getMember(String name) { 332 MemberItem result = null; 333 try { 334 if (name.indexOf('(')!=-1) 335 result = getAbstractMethod(name); 336 else 337 result = getField(name); 338 } catch(NoSuchFieldException e) { 339 if (result==null) { 340 try { 341 result = getAbstractMethod(name); 342 } catch (NoSuchMethodException e2) { 343 throw new NoSuchMemberException(this,name); 344 } 345 } 346 } 347 return result; 348 } 349 350 359 public MemberItem[] getMembers(String [] names) { 360 MemberItem[] tmp = new MemberItem[names.length]; 361 int j = 0; 362 for(int i=0; i<names.length; i++) { 363 try { 364 tmp[j] = getMember(names[i]); 365 j++; 366 } catch (NoSuchMemberException e) { 367 logger.warn(e); 368 } 369 } 370 MemberItem[] members = new MemberItem[j]; 371 System.arraycopy(tmp,0,members,0,j); 372 return members; 373 } 374 375 public Collection getAllMembers() { 376 Collection result = getAllMethods(); 377 result.addAll(getAllFields()); 378 return result; 379 } 380 381 389 public FieldItem[] getFields(String [] names) { 390 FieldItem[] tmp = new FieldItem[names.length]; 391 int j=0; 392 for(int i=0;i<names.length;i++) { 393 try { 394 tmp[j] = getField(names[i]); 395 j++; 396 } catch (NoSuchFieldException e) { 397 logger.warn(e); 398 } 399 } 400 FieldItem[] fields = new FieldItem[j]; 401 System.arraycopy(tmp,0,fields,0,j); 402 return fields; 403 } 404 405 406 415 public MethodItem[] getMethods(String [] names) { 416 MethodItem[] tmp = new MethodItem[names.length]; 417 int j=0; 418 for(int i=0;i<names.length;i++) { 419 try { 420 tmp[j] = getMethod(names[i]); 421 j++; 422 } catch (NoSuchMethodException e) { 423 logger.warn(e); 424 } 425 } 426 MethodItem[] methods = new MethodItem[j]; 427 System.arraycopy(tmp,0,methods,0,j); 428 return methods; 429 } 430 431 436 437 public FieldItem[] getPrimitiveFields() { 438 buildFieldInfo(); 439 Collection c = fields.values(); 440 FieldItem[] res = new FieldItem[primsCount]; 441 Iterator it = c.iterator(); 442 int i = 0; 443 while ( it.hasNext() ) { 444 FieldItem field = (FieldItem) it.next(); 445 if (field.isPrimitive()) { 446 res[i] = field; 447 i++; 448 } 449 } 450 return res; 451 } 452 453 458 459 public FieldItem[] getReferences() { 460 buildFieldInfo(); 461 Collection c = fields.values(); 462 FieldItem[] res = new FieldItem[refsCount]; 463 Iterator it = c.iterator(); 464 int i = 0; 465 while ( it.hasNext() ) { 466 FieldItem field = (FieldItem) it.next(); 467 if (field.isReference()) { 468 res[i] = field; 469 i++; 470 } 471 } 472 return res; 473 } 474 475 480 481 public Collection getMatchingRelations(String expr) { 482 buildFieldInfo(); 483 Vector res = new Vector (); 484 Collection c = fields.values(); 485 Iterator it = c.iterator(); 486 RE re; 487 try { 488 re = new RE(expr); 489 } catch (Exception e) { 490 logger.error("getMatchingRelations "+expr,e); 491 return null; 492 } 493 while (it.hasNext()) { 494 FieldItem field = (FieldItem) it.next(); 495 if (field.isReference() || (field instanceof CollectionItem)) { 496 if (re.isMatch(field.getName())) { 497 res.add( field ); 498 } 499 } 500 } 501 return res; 502 } 503 504 509 510 public CollectionItem[] getCollections() { 511 buildFieldInfo(); 512 Collection c = fields.values(); 513 CollectionItem[] res = new CollectionItem[collsCount]; 514 Iterator it = c.iterator(); 515 int i = 0; 516 while ( it.hasNext() ) { 517 FieldItem field = (FieldItem) it.next(); 518 if (field instanceof CollectionItem) { 519 res[i] = (CollectionItem)field; 520 i++; 521 } 522 } 523 return res; 524 } 525 526 532 void addField(FieldItem field) { 533 buildFieldInfo(); 534 boolean override = fields.containsKey(field.getName()); 535 if (override) { 536 logger.warn("Overriding field "+fields.get(field.getName())+ 537 " with "+field); 538 } 539 try { 540 field.setParent(this); 541 } catch(Exception e) { 542 logger.error("addField "+field.getName(),e); 543 return; 544 } 545 fields.put(field.getName(), field); 546 if (field instanceof CollectionItem && !override) { 547 collsCount++; 548 } else if (field.isReference() && !override) { 549 refsCount++; 550 } else if (!override) { 551 primsCount++; 552 } 553 } 554 555 562 public AbstractMethodItem[] getAbstractMethods(String name) 563 throws NoSuchMethodException 564 { 565 if (name.startsWith("<init>")) 566 name = getShortName()+name.substring(6); 567 AbstractMethodItem[] res=null; 569 if (name.endsWith(")")) { 570 String name2 = name.substring(0,name.indexOf("(")); 571 AbstractMethodItem[] meths = 573 (AbstractMethodItem[])methods.get(name2); 574 if (meths!=null) { 575 for (int i=0; i<meths.length; i++) { 576 if (meths[i].getFullName().endsWith(name)) { 578 res = new AbstractMethodItem[] {meths[i]}; 579 } 580 } 581 } 582 } else { 583 res = (AbstractMethodItem[])methods.get(name); 584 } 585 if (res == null) { 586 throw new NoSuchMethodException ( 587 "ClassItem.getAbstractMethods: no such method "+name+" in "+this); 588 } 589 return res; 590 } 591 592 Hashtable methodCache = new Hashtable (); 593 594 608 public AbstractMethodItem getAbstractMethod(String name) 609 throws NoSuchMethodException , AmbiguousMethodNameException 610 { 611 AbstractMethodItem cachedMethod = 612 (AbstractMethodItem)methodCache.get(name); 613 if (cachedMethod!=null) { 614 return cachedMethod; 615 } else { 616 AbstractMethodItem[] res = getAbstractMethods(name); 617 if (res.length>1) { 618 throw new NoSuchMethodException ("Ambiguous method name "+ 619 this+"."+name); 620 } 621 methodCache.put(name,res[0]); 622 return res[0]; 623 } 624 } 625 626 635 public boolean hasMethod(String name, Class [] paramTypes) { 636 try { 637 ((Class )delegate).getDeclaredMethod(name,paramTypes); 638 return true; 639 } catch(java.lang.NoSuchMethodException e) { 640 return false; 641 } 642 } 643 644 650 static String stripArgs(String name) { 651 int index = name.indexOf("("); 652 if (index!=-1) 653 return name.substring(0,index); 654 else 655 return name; 656 } 657 658 664 665 public MethodItem[] getMethods(String name) 666 throws NoSuchMethodException 667 { 668 MethodItem[] res = null; 669 670 if (name.endsWith(")")) { 672 String name2 = name.substring(0,name.indexOf("(")); 673 MethodItem[] meths = (MethodItem[])methods.get(name2); 675 if (meths!=null) { 676 for (int i=0; i<meths.length; i++) { 677 if (meths[i].getFullName().endsWith(name)) { 679 res = new MethodItem[] {meths[i]}; 680 } 681 } 682 } 683 } else { 684 res = (MethodItem[])methods.get(name); 685 } 686 687 692 693 if (res == null) { 694 throw new NoSuchMethodException ( 696 "ClassItem.getMethods: no such method "+name+" in class "+this); 697 } 698 return res; 699 } 700 701 714 715 public MethodItem getMethod(String name) 716 throws NoSuchMethodException , AmbiguousMethodNameException 717 { 718 MethodItem[] res= getMethods(name); 720 if (res.length>1) { 721 throw new AmbiguousMethodNameException( 722 "Ambiguous method name "+this+"."+name+" choice is:" 723 +java.util.Arrays.asList(res)); 724 } 725 return res[0]; 726 } 727 728 736 public Collection getMethods() { 737 Collection c = methods.values(); 738 Vector res = new Vector (); 739 Iterator it = c.iterator(); 740 while (it.hasNext()) { 741 Object [] methods = (Object []) it.next(); 742 if (methods[0] instanceof MethodItem) { 743 res.add(methods); 744 } 745 } 746 return res; 747 } 748 749 754 public Collection getAllMethods() { 755 Collection c = methods.values(); 756 Vector res = new Vector (); 757 Iterator it = c.iterator(); 758 while (it.hasNext()) { 759 Object [] methods = (Object []) it.next(); 760 for (int i=0; i<methods.length; i++) { 761 if ( methods[i] instanceof MethodItem && 762 !ClassRepository.isJacMethod( 763 ((MethodItem)methods[i]).getName()) ) { 764 res.add(methods[i]); 765 } 766 } 767 } 768 return res; 769 } 770 771 776 public Collection getMixinMethods() { 777 Collection c = methods.values(); 778 Vector res = new Vector (); 779 Iterator it = c.iterator(); 780 while (it.hasNext()) { 781 Object [] methods = (Object []) it.next(); 782 for (int i=0; i<methods.length; i++) { 783 if ( methods[i] instanceof MixinMethodItem && 784 !ClassRepository.isJacMethod( 785 ((MethodItem)methods[i]).getName()) ) { 786 res.add(methods[i]); 787 } 788 } 789 } 790 return res; 791 } 792 793 796 public Collection getAllStaticMethods() { 797 Collection c = methods.values(); 798 Vector res = new Vector (); 799 Iterator it = c.iterator(); 800 while (it.hasNext()) { 801 Object [] methods = (Object []) it.next(); 802 for (int i=0; i<methods.length; i++) { 804 if ( methods[i] instanceof MethodItem && 805 !ClassRepository.isJacMethod( 806 ((MethodItem)methods[i]).getName()) && 807 ((MethodItem)methods[i]).isStatic()) { 808 res.add(methods[i]); 810 } 811 } 812 } 813 return res; 814 } 815 816 819 public Collection getAllInstanceMethods() { 820 Collection c = methods.values(); 821 Vector res = new Vector (); 822 Iterator it = c.iterator(); 823 while (it.hasNext()) { 824 Object [] methods = (Object []) it.next(); 825 for (int i=0; i<methods.length; i++) { 826 if ( methods[i] instanceof MethodItem && 827 !ClassRepository.isJacMethod( 828 ((MethodItem)methods[i]).getName()) && 829 !((MethodItem)methods[i]).isStatic()) { 830 res.add(methods[i]); 831 } 832 } 833 } 834 return res; 835 } 836 837 843 public Collection getAllModifiers() { 844 Iterator it = getAllMethods().iterator(); 845 Vector modifiers = new Vector (); 846 while(it.hasNext()) { 847 MethodItem method = (MethodItem)it.next(); 848 if (method.isModifier()) { 849 modifiers.add(method); 850 } 851 } 852 return modifiers; 853 } 854 855 856 862 public Collection getAllSetters() { 863 Iterator it = getAllMethods().iterator(); 864 Vector modifiers = new Vector (); 865 while(it.hasNext()) { 866 MethodItem method = (MethodItem)it.next(); 867 if (method.isSetter()) { 868 modifiers.add(method); 869 } 870 } 871 return modifiers; 872 } 873 874 880 public Collection getAllWriters() { 881 Iterator it = getAllMethods().iterator(); 882 Vector modifiers = new Vector (); 883 while(it.hasNext()) { 884 MethodItem method = (MethodItem)it.next(); 885 if (method.hasWrittenFields()) { 886 modifiers.add(method); 887 } 888 } 889 return modifiers; 890 } 891 892 898 public Collection getAllGetters() { 899 Vector modifiers = new Vector (); 900 Iterator it = getAllMethods().iterator(); 901 while(it.hasNext()) { 902 MethodItem method = (MethodItem)it.next(); 903 if (method.isGetter()) { 904 modifiers.add(method); 905 } 906 } 907 return modifiers; 908 } 909 910 916 public Collection getAllAccessors() { 917 Vector accessors = new Vector (); 918 Iterator it = getAllMethods().iterator(); 919 while(it.hasNext()) { 920 MethodItem method = (MethodItem)it.next(); 921 if (method.isAccessor()) { 922 accessors.add(method); 923 } 924 } 925 return accessors; 926 } 927 928 929 935 public Collection getAllRemovers() { 936 Vector removers = new Vector (); 937 Iterator it = getAllMethods().iterator(); 938 while(it.hasNext()) { 939 MethodItem method = (MethodItem)it.next(); 940 if (method.isRemover()) { 941 removers.add(method); 942 } 943 } 944 return removers; 945 } 946 947 953 public Collection getAllAdders() { 954 Collection methods = getAllMethods(); 955 Iterator it = methods.iterator(); 956 Vector adders = new Vector (); 957 958 while(it.hasNext()) { 959 MethodItem method = (MethodItem)it.next(); 960 if (method.getAddedCollections() != null && 961 method.getAddedCollections().length>0) { 962 adders.add(method); 963 } 964 } 965 return adders; 966 } 967 968 973 public Collection getConstructors() { 974 Collection c = methods.values(); 975 Vector res = new Vector (); 976 Iterator it = c.iterator(); 977 while ( it.hasNext() ) { 978 Object [] methods = (Object []) it.next(); 979 if (methods[0] instanceof ConstructorItem) { 981 res.addAll(java.util.Arrays.asList(methods)); 983 } 984 } 985 return res; 986 } 987 988 public ConstructorItem getConstructor(Class [] parameterTypes) 989 throws NoSuchMethodException 990 { 991 Iterator i = getConstructors().iterator(); 992 while (i.hasNext()) { 993 ConstructorItem constructor = (ConstructorItem)i.next(); 994 if (java.util.Arrays.equals(constructor.getParameterTypes(), 995 parameterTypes)) { 996 return constructor; 997 } 998 } 999 return null; 1000 } 1001 1002 1007 public ConstructorItem getConstructor(String parameterTypes) { 1008 return (ConstructorItem)getAbstractMethod(getShortName()+parameterTypes); 1009 } 1010 1011 1017 public ConstructorItem getConstructor(Constructor constructor) { 1018 Collection constructors = getConstructors(); 1020 Iterator it = constructors.iterator(); 1021 while ( it.hasNext() ) { 1022 ConstructorItem[] current = (ConstructorItem[])it.next(); 1023 for (int i=0; i<current.length; i++) { 1024 if (current[i].getActualConstructor().toString().equals(constructor.toString())) { 1026 return current[i]; 1027 } 1028 } 1029 } 1030 return null; 1031 } 1032 1033 1038 1039 public Object newInstance() 1040 throws InstantiationException , IllegalAccessException { 1041 return getActualClass().newInstance(); 1042 } 1043 1044 1051 1052 public Object newInstance(Class [] types,Object [] values) 1053 throws InstantiationException , IllegalAccessException , 1054 java.lang.NoSuchMethodException , InvocationTargetException { 1055 Constructor c = getActualClass().getConstructor(types); 1056 return c.newInstance(values); 1057 } 1058 1059 1064 public Object newInstance(Object [] parameters) 1065 throws InstantiationException , IllegalAccessException , 1066 java.lang.NoSuchMethodException , InvocationTargetException 1067 { 1068 Iterator i = getConstructors().iterator(); 1069 ConstructorItem constructor = null; 1070 while (i.hasNext()) { 1071 constructor = (ConstructorItem)i.next(); 1072 Class [] parameterTypes = constructor.getParameterTypes(); 1073 if (parameterTypes.length==parameters.length) { 1074 int j; 1075 for (j=0; j<parameters.length; j++) { 1076 if (!parameterTypes[j] 1079 .isAssignableFrom(parameters[j].getClass())) { 1080 break; 1081 } 1082 } 1083 if (j==parameters.length) { 1084 return constructor.newInstance(parameters); 1085 } 1086 } 1087 } 1088 throw new InstantiationException ( 1089 "Could not find a suitable constructor for class "+getName()+ 1090 " with arguments "+java.util.Arrays.asList(parameters)); 1091 } 1092 1093 1099 1100 public Class getActualClass() { 1101 return (Class )delegate; 1102 } 1103 1104 ClassItem[] interfaceItems = null; 1105 1108 public ClassItem[] getInterfaceItems() { 1109 if (interfaceItems==null) { 1110 Class [] interfaces = getActualClass().getInterfaces(); 1111 interfaceItems = new ClassItem[interfaces.length]; 1112 ClassRepository cr = ClassRepository.get(); 1113 for (int i=0; i<interfaces.length; i++) { 1114 interfaceItems[i] = cr.getClass(interfaces[i]); 1115 } 1116 } 1117 return interfaceItems; 1118 } 1119 1120 1121 ClassItem superClass; 1122 1123 1128 protected void setSuperClass(ClassItem superClass) { 1129 this.superClass = superClass; 1130 superClass.addChild(this); 1131 } 1132 1133 1138 public ClassItem getSuperclass() { 1139 return superClass; 1140 } 1141 1142 1143 Vector children = new Vector (); 1144 1145 public Collection getChildren() { 1146 return children; 1147 } 1148 1149 public void addChild(ClassItem child) { 1150 children.add(child); 1151 } 1152 1153 1158 public boolean isSubClassOf(RE classNameRE) { 1159 if (classNameRE.isMatch(getName())) { 1160 return true; 1161 } else if (superClass!=null) { 1162 return superClass.isSubClassOf(classNameRE); 1163 } else { 1164 ClassItem[] interfaces = getInterfaceItems(); 1165 for (int i=0; i<interfaces.length; i++) { 1166 if (interfaces[i].isSubClassOf(classNameRE)) 1167 return true; 1168 } 1169 return false; 1170 } 1171 } 1172 1173 1178 public boolean isSubClassOf(ClassItem cl) { 1179 if (cl==this) { 1180 return true; 1181 } else if (superClass!=null) { 1182 return superClass.isSubClassOf(cl); 1183 } else { 1184 ClassItem[] interfaces = getInterfaceItems(); 1185 for (int i=0; i<interfaces.length; i++) { 1186 if (interfaces[i].isSubClassOf(cl)) 1187 return true; 1188 } 1189 return false; 1190 } 1191 } 1192 1193 public int getModifiers() { 1194 return ((Class )delegate).getModifiers(); 1195 } 1196 1197 1203 1204 public Class getType() { 1205 return getActualClass(); 1206 } 1207 1208 1213 public void addMethod(MethodItem method) { 1214 String name = method.getName(); 1215 if (!methods.containsKey(name)) { 1217 methods.put(name, new MethodItem[] { method } ); 1218 } else { 1219 MethodItem[] meths = (MethodItem[])methods.get(name); 1220 MethodItem[] newMeths = new MethodItem[meths.length + 1]; 1221 System.arraycopy(meths, 0, newMeths, 0, meths.length); 1222 newMeths[meths.length] = method; 1223 methods.remove(name); 1224 methods.put(name, newMeths); 1225 } 1226 methodsCount++; 1227 if (method instanceof MixinMethodItem) { 1228 Iterator i = children.iterator(); 1229 while (i.hasNext()) { 1230 ClassItem subclass = (ClassItem)i.next(); 1231 subclass.addMethod(method); 1232 } 1233 } 1234 try { 1235 method.setParent(this); 1236 } catch(Exception e) { 1237 logger.error("addMethod "+method.getFullName()+ 1238 ": could not set the parent of the method",e); 1239 } 1240 } 1241 1242 Vector mixinMethods = new Vector (); 1243 1244 1249 public void addConstructor(ConstructorItem constructor) { 1250 String name = NamingConventions.getShortConstructorName(constructor.getActualConstructor()); 1251 if ( ! methods.containsKey( name )) { 1253 methods.put( name, new ConstructorItem[] { constructor } ); 1254 } else { 1255 ConstructorItem[] constructors = 1256 (ConstructorItem[]) methods.get( name ); 1257 ConstructorItem[] newConstructors = 1258 new ConstructorItem[constructors.length + 1]; 1259 System.arraycopy(constructors, 0, newConstructors, 0, constructors.length); 1260 newConstructors[constructors.length] = constructor; 1261 methods.remove(constructor.getName()); 1262 methods.put(name, newConstructors); 1263 } 1264 constructorsCount++; 1265 try { 1266 constructor.setParent(this); 1267 } catch( Exception e ) { 1268 logger.error("addConstructor "+constructor.getFullName(),e); 1269 } 1270 } 1271 1272 1277 public boolean hasMethod(String name) { 1278 try { 1279 getAbstractMethod(name); 1280 return true; 1281 } catch (NoSuchMethodException e) { 1282 return false; 1283 } catch (AmbiguousMethodNameException e) { 1284 return true; 1285 } 1286 } 1287 1288 public boolean hasMethod(MethodItem method) { 1289 return method.parent==this; 1290 } 1291 1292 1297 1298 public boolean hasField( String name ) { 1299 buildFieldInfo(); 1300 return (name!=null) && fields.containsKey( name ); 1301 } 1302 1303 public String getName() { 1304 return ((Class )delegate).getName(); 1305 } 1306 1307 public String getShortName() { 1308 String name = getName(); 1309 int index = name.lastIndexOf('.'); 1310 return index==-1 ? name : name.substring(index+1); 1311 } 1312 1313 1321 1322 public Object invoke(Object object, String methodName, Object [] parameters) 1323 throws IllegalAccessException , InvocationTargetException 1324 { 1325 return getMethod(methodName).invoke(object, parameters); 1326 } 1327 1328 1333 public boolean isInner() { 1334 return getName().indexOf('$')!=-1; 1335 } 1336 1337 public boolean isAbstract() { 1338 return Modifier.isAbstract(getModifiers()); 1339 } 1340 1341 1346 public ClassItem getOwnerClassItem() { 1347 int index = getName().indexOf('$'); 1348 if (index==-1) { 1349 return null; 1350 } else { 1351 return ClassRepository.get().getClass(getName().substring(0,index)); 1352 } 1353 } 1354 1355 1363 1364 public CollectionItem findCollectionFor(Object substance,Object object) { 1365 CollectionItem[] collections=getCollections(); 1366 for(int i=0;i<collections.length;i++) { 1367 Collection cur=collections[i].getActualCollection(substance); 1368 if(cur.contains(object)) { 1369 return collections[i]; 1370 } 1371 } 1372 return null; 1373 } 1374 1375 1378 public Object getAttribute(String name) { 1379 ClassItem cur = this; 1380 Object result = null; 1381 while (cur!=null && result==null) { 1382 result = cur.superGetAttribute(name); 1383 cur = cur.getSuperclass(); 1384 } 1385 return result; 1386 } 1387 1388 public Object superGetAttribute(String name) { 1389 return super.getAttribute(name); 1390 } 1391 1392 Vector constraints; 1393 1398 public Collection getConstraints() { 1399 if (constraints==null) { 1400 constraints = new Vector (); 1401 Object [] classes = ClassRepository.get().getClasses(); 1402 for (int i=0; i<classes.length;i++) { 1403 if (classes[i] instanceof ClassItem) { 1404 ClassItem cl = (ClassItem)classes[i]; 1405 FieldItem[] fields = cl.getFields(); 1406 for (int j=0; j<fields.length; j++) { 1407 if (fields[j] instanceof CollectionItem) { 1408 if (((CollectionItem)fields[j]).getComponentType()==this) 1409 constraints.add(fields[j]); 1410 } else if (fields[j].getTypeItem()==this) { 1411 constraints.add(fields[j]); 1412 } 1413 } 1414 } 1415 } 1416 } 1417 return constraints; 1418 } 1419 1420 1424 public static class AmbiguousMethodNameException extends RuntimeException { 1425 public AmbiguousMethodNameException(String msg) { super(msg); } 1426 public AmbiguousMethodNameException() { super(); } 1427 } 1428} 1429 | Popular Tags |