1 18 19 package org.objectweb.jac.core.rtti; 20 21 import java.lang.reflect.Constructor ; 22 import java.lang.reflect.Field ; 23 import java.lang.reflect.InvocationTargetException ; 24 import java.lang.reflect.Method ; 25 import java.lang.reflect.Modifier ; 26 import java.util.Arrays ; 27 import java.util.Collection ; 28 import java.util.Enumeration ; 29 import java.util.Hashtable ; 30 import java.util.Iterator ; 31 import java.util.Map ; 32 import java.util.Vector ; 33 import org.apache.log4j.Logger; 34 import org.objectweb.jac.util.Classes; 35 import org.objectweb.jac.util.Strings; 36 37 51 52 public class ClassRepository implements LoadtimeRTTI { 53 static Logger logger = Logger.getLogger("rtti.repository"); 54 static Logger loggerlt = Logger.getLogger("rtti.lt"); 55 56 Map ltClassInfos = new Hashtable (); 57 58 public ClassInfo getClassInfo(String className) { 59 ClassInfo classinfo=(ClassInfo)ltClassInfos.get(className); 60 if (classinfo==null) { 61 classinfo=new ClassInfo(); 62 ltClassInfos.put(className,classinfo); 63 } 64 return classinfo; 65 } 66 67 public void setClassInfo(String className, ClassInfo classInfo) { 68 ltClassInfos.put(className,classInfo); 69 } 70 71 public MethodInfo getMethodInfo(String className, String method) { 72 return getClassInfo(className).getMethodInfo(method); 73 } 74 75 85 86 public void addltModifiedField(String className, String methodSign, 87 String fieldName) { 88 getClassInfo(className).addModifiedField(methodSign,fieldName); 89 } 90 91 public void addltSetField(String className, String methodSign, 92 String fieldName) { 93 getClassInfo(className).addSetField(methodSign,fieldName); 94 } 95 96 106 107 public void addltAccessedField(String className, String methodSign, 108 String fieldName) { 109 getClassInfo(className).addAccessedField(methodSign,fieldName); 110 } 111 112 public void addltReturnedField(String className, String methodSign, 113 String fieldName) { 114 getClassInfo(className).setReturnedField(methodSign,fieldName); 115 } 116 117 public void setltIsGetter(String className, String methodSign, 118 boolean isGetter) { 119 getClassInfo(className).setIsGetter(methodSign,isGetter); 120 } 121 122 public void addltAddedCollection(String className, String methodSign, 123 String fieldName) { 124 getClassInfo(className).addAddedCollection(methodSign,fieldName); 125 } 126 127 public void addltRemovedCollection(String className, String methodSign, 128 String fieldName) { 129 getClassInfo(className).addRemovedCollection(methodSign,fieldName); 130 } 131 132 public void addltModifiedCollection(String className, String methodSign, 133 String fieldName) { 134 getClassInfo(className).addModifiedCollection(methodSign,fieldName); 135 } 136 137 public void setCollectionIndexArgument(String className, String methodSign, 138 int argument) { 139 getClassInfo(className).setCollectionIndexArgument(methodSign,argument); 140 } 141 142 public void setCollectionItemArgument(String className, String methodSign, 143 int argument) { 144 getClassInfo(className).setCollectionItemArgument(methodSign,argument); 145 } 146 147 public void addInvokedMethod(String className, String methodSign, 148 InvokeInfo invokeInfo) { 149 getClassInfo(className).addInvokedMethod(methodSign,invokeInfo); 150 } 151 152 public void setCallSuper(String className, String method) { 153 getMethodInfo(className,method).callSuper = true; 154 } 155 156 160 161 public static ClassRepository get() { 162 if ( classRepository == null ) { 163 classRepository = new ClassRepository(); 164 } 165 return classRepository; 166 } 167 168 170 171 protected static transient ClassRepository classRepository = null; 172 173 174 176 public static Class wrappeeClass; 177 static { 178 try { 179 wrappeeClass = Class.forName("org.objectweb.jac.core.Wrappee"); 181 } catch(Exception e) { 182 e.printStackTrace(); 183 System.exit( -1 ); 184 } 185 } 186 187 190 transient static Hashtable directMethodAccess = new Hashtable (); 191 192 195 transient static Hashtable directFieldAccess = new Hashtable (); 196 197 206 207 public static Hashtable fillDirectMethodAccess(final Class cl) { 208 if( cl == null ) return null; 209 if ( directMethodAccess == null ) directMethodAccess = new Hashtable (); 210 Hashtable methods = new Hashtable (); 211 final Method [] meths = cl.getMethods(); 212 for (int i=meths.length-1; i>=0; i--) { 214 meths[i].setAccessible(true); 215 if ( methods.containsKey(meths[i].getName()) ) { 216 Method [] oldms = (Method []) methods.get( meths[i].getName() ); 217 Method [] newms = new Method [oldms.length+1]; 218 System.arraycopy( oldms, 0, newms, 0, oldms.length ); 219 newms[oldms.length] = meths[i]; 220 methods.remove( meths[i].getName() ); 221 methods.put( meths[i].getName(), newms ); 222 } else { 223 methods.put( meths[i].getName(), new Method [] { meths[i] } ); 224 } 225 } 226 directMethodAccess.put(cl,methods); 227 return methods; 228 } 229 230 237 238 public static void fillDirectFieldAccess(final Class cl) { 239 if (cl==null || cl==Object .class) 240 return; 241 if (directFieldAccess == null ) 242 directFieldAccess = new Hashtable (); 243 if (directFieldAccess.containsKey(cl)) 244 return; 245 Hashtable fields = new Hashtable (); 246 Class superClass = cl.getSuperclass(); 247 if (superClass!=Object .class && superClass!=null) { 248 fillDirectFieldAccess(superClass); 249 Map inheritedFields = (Map )directFieldAccess.get(superClass); 250 if (inheritedFields!=null) 251 fields.putAll(inheritedFields); 252 } 253 final Field [] fs = cl.getDeclaredFields(); 254 for (int i = 0; i<fs.length; i++) { 256 if (!isJacField(fs[i].getName()) && !isSystemField(fs[i].getName())) { 257 fs[i].setAccessible(true); 258 fields.put(fs[i].getName(),fs[i]); 259 } 260 } 261 directFieldAccess.put(cl,fields); 262 } 263 264 275 276 public static Hashtable getDirectFieldAccess(Class cl) { 277 fillDirectFieldAccess(cl); 278 return ((Hashtable )directFieldAccess.get(cl)); 279 } 280 281 291 public static Object invokeDirect(Class cl, 292 String methodName, 293 Object o, 294 Object [] params) 295 throws java.lang.NoSuchMethodException , 296 InvocationTargetException , IllegalAccessException 297 { 298 Method [] directMethods = getDirectMethodAccess(cl,methodName); 299 logger.debug("direct invocation of "+methodName+" => "+ 300 java.util.Arrays.asList(directMethods)); 301 boolean ok = false; 302 boolean lengthOk = false; 303 Object ret = null; 304 for (int i=0; i<directMethods.length; i++) { 305 if (directMethods[i].getParameterTypes().length==params.length) { 306 lengthOk = true; 307 try { 308 ret = directMethods[i].invoke(o, params); 309 ok = true; 310 } catch (IllegalArgumentException e1) { 311 } 312 } 313 } 314 if (!ok) { 315 if (lengthOk) { 316 logger.error("No such method "+cl.getName()+"."+methodName+Arrays.asList(params)); 317 } else { 318 logger.error("Wrong number of parameters for "+cl.getName()+"."+methodName+Arrays.asList(params)); 319 } 320 throw new java.lang.NoSuchMethodException (); 321 } 322 return ret; 323 } 324 325 341 public static Method [] getDirectMethodAccess(Class cl, String name) { 342 Hashtable methods = (Hashtable )directMethodAccess.get(cl); 343 if (methods==null) 344 methods = fillDirectMethodAccess(cl); 345 Method [] ret = (Method []) methods.get(name); 346 if (ret == null ) { 347 return new Method [] { }; 348 } else { 349 return ret; 350 } 351 } 352 353 360 public static boolean isDefaultConstructorAdded(Class cl) { 361 try { 362 cl.getField("__JAC_ADDED_DEFAULT_CONSTRUCTOR"); 363 } catch (Exception e) { 364 return false; 365 } 366 return true; 367 } 368 369 375 public static boolean isJacMethod (String methodName) { 376 if (methodName.startsWith("_")) 377 return true; 378 return false; 379 } 380 381 385 public static boolean isJacField (String fieldName) { 386 return 387 fieldName.startsWith("__JAC_") || 388 fieldName.equals("JUST4LOG_OPTIMIZED"); 389 } 390 391 396 public static boolean isSystemField(String fieldName) { 397 return fieldName.indexOf('$')!=-1; 398 } 399 400 406 public static String [] getMethodsName(Class cl) { 407 408 String [] methodNames = null; 409 Vector tmp = new Vector (); 410 411 try { 412 413 Method [] methods = cl.getMethods(); 414 415 for (int i=0; i<methods.length; i++) { 416 if ( ! ( Modifier.isStatic(methods[i].getModifiers()) || 417 isJacMethod(methods[i].getName()) ) ) { 418 tmp.add (methods[i].getName()); 419 } 420 } 421 422 methodNames = new String [tmp.size()]; 423 424 for (int i=0 ; i<tmp.size(); i++) { 425 methodNames[i] = (String )tmp.get(i); 426 } 427 428 } catch(Exception e) { 429 logger.error("getMethodsName "+cl.getName()+" failed",e); 430 } 431 432 return methodNames; 433 } 434 435 441 public static String [] getModifiersNames(Class cl) { 442 443 ClassItem cli = ClassRepository.get().getClass(cl); 444 Collection modifiers = cli.getAllModifiers(); 445 446 String [] methodNames = new String [modifiers.size()]; 447 448 Iterator it = modifiers.iterator(); 449 for( int i=0; i<methodNames.length; i++ ) { 450 methodNames[i]=((MethodItem)it.next()).getName(); 451 } 452 return methodNames; 453 } 454 455 461 public static String [] getGettersNames(Class cl) { 462 463 ClassItem cli = ClassRepository.get().getClass(cl); 464 Collection getters = cli.getAllGetters(); 465 466 String [] methodNames = new String [getters.size()]; 467 468 Iterator it = getters.iterator(); 469 for( int i=0; i<methodNames.length; i++ ) { 470 methodNames[i]=((MethodItem)it.next()).getName(); 471 } 472 return methodNames; 473 } 474 475 488 public static void addWrittenFields(Class cl, 489 String methodName, 490 String [] fieldNames) 491 { 492 ClassItem cli = ((ClassRepository)ClassRepository.get()).getClass(cl); 493 MethodItem[] mis = cli.getMethods(methodName); 494 495 if ( mis != null ) { 496 for ( int i = 0; i < mis.length; i++ ) { 497 for ( int j = 0; j < fieldNames.length; j++ ) { 498 FieldItem fi = cli.getField( fieldNames[j] ); 499 if ( fi != null ) { 500 mis[i].addWrittenField(fi); 501 } 502 } 503 } 504 } 505 506 } 507 508 521 public static void addAccessedFields(Class cl, 522 String methodName, 523 String [] fieldNames) { 524 525 ClassItem cli = ClassRepository.get().getClass(cl); 526 MethodItem[] mis = cli.getMethods(methodName); 527 528 if ( mis != null ) { 529 for ( int i = 0; i < mis.length; i++ ) { 530 for ( int j = 0; j < fieldNames.length; j++ ) { 531 FieldItem fi = cli.getField( fieldNames[j] ); 532 if ( fi != null ) { 533 mis[i].addAccessedField(fi); 534 } 535 } 536 } 537 } 538 539 } 540 541 554 public static void addAddedCollections(Class cl, 555 String methodName, 556 String [] collectionNames) { 557 558 ClassItem cli = ClassRepository.get().getClass(cl); 559 MethodItem[] mis = cli.getMethods(methodName); 560 561 if ( mis != null ) { 562 for ( int i = 0; i < mis.length; i++ ) { 563 for ( int j = 0; j < collectionNames.length; j++ ) { 564 CollectionItem ci = (CollectionItem)cli.getField(collectionNames[j]); 565 if ( ci != null ) { 566 mis[i].addAddedCollection(ci); 567 } 568 } 569 } 570 } 571 572 } 573 574 587 public static void addRemovedCollections(Class cl, 588 String methodName, 589 String [] collectionNames) { 590 591 ClassItem cli = ClassRepository.get().getClass(cl); 592 MethodItem[] mis = cli.getMethods(methodName); 593 594 if (mis != null) { 595 for (int i=0; i<mis.length; i++) { 596 for (int j=0; j<collectionNames.length; j++) { 597 CollectionItem ci = (CollectionItem)cli.getField(collectionNames[j]); 598 if (ci != null) { 599 mis[i].addRemovedCollection(ci); 600 } 601 } 602 } 603 } 604 605 } 606 607 610 611 public ClassRepository () { 612 classRepository = this; 613 } 614 615 631 public ClassItem getClass(String name) 632 { 633 String wrappedName = Classes.getPrimitiveTypeWrapper(name); 634 MetaItem res = (MetaItem)getObject(wrappedName); 635 if (res == null) { 636 try { 637 res = getClass(Class.forName(name)); 638 } catch (ClassNotFoundException e) { 639 throw new NoSuchClassException(name); 640 } 641 } 642 if (res!=null && res instanceof ClassItem) 643 return (ClassItem)res; 644 else 645 throw new NoSuchClassException(name); 646 } 647 648 659 660 public MetaItem getVirtualClass(String name) 661 { 662 MetaItem ret; 663 try { 664 ret = getClass(name); 665 } catch (NoSuchClassException e) { 666 ret = (MetaItem)getObject(name); 667 if (ret == null) 668 throw e; 669 } 670 return ret; 671 } 672 673 680 public VirtualClassItem getVirtualClassStrict(String name) 681 { 682 MetaItem ret; 683 ret = (MetaItem)getObject(name); 684 if (ret == null || !(ret instanceof VirtualClassItem)) 685 throw new NoSuchClassException(name); 686 return (VirtualClassItem)ret; 687 } 688 689 696 697 public ClassItem getClass(Object object) { 698 return getNonPrimitiveClass(object.getClass().getName()); 699 } 700 708 public ClassItem getClass(Class cl) { 709 String wrappedName = Classes.getPrimitiveTypeWrapper(cl.getName()); 710 MetaItem res = (MetaItem)getObject(wrappedName); 711 if (res == null) { 712 res = buildDefaultRTTI(cl); 713 if (res != null) 714 register(wrappedName, res); 715 } 716 if (res!=null && res instanceof ClassItem) 717 return (ClassItem)res; 718 else 719 throw new NoSuchClassException(cl.getName()); 720 721 } 722 723 public ClassItem getNonPrimitiveClass(String className) { 724 try { 725 Class cl = Class.forName(className); 728 MetaItem res = (MetaItem)getObject(className); 729 if (res == null) { 730 try { 731 res = buildDefaultRTTI(cl); 732 } catch(Exception e) { 733 throw new NoSuchClassException(className); 734 } 735 if (res != null) { 736 register(className, res); 737 return (ClassItem)res; 738 } 739 } else { 740 return (ClassItem)res; 741 } 742 throw new NoSuchClassException(className); 743 } catch(ClassNotFoundException e) { 744 throw new NoSuchClassException(className); 745 } 746 } 747 748 String ignoreFields = null; 749 public void ignoreFields(String packageExpr) { 750 ignoreFields = packageExpr; 751 } 752 753 761 public ClassItem buildDefaultRTTI(Class cl) { 762 ClassItem cli = null; 763 logger.debug( ">>> Constructing RTTI infos for class "+cl.getName()+Strings.hash(cl)); 764 try { 765 766 cli = new ClassItem(cl); 767 768 Method [] meths = cl.getMethods(); 770 for(int i=0; i<meths.length; i++) { 772 if (meths[i].getDeclaringClass() == Object .class 773 ) continue; 774 Logger.getLogger("rtti."+cl.getName()).debug(" adding method "+meths[i]); 775 MethodItem mi = new MethodItem(meths[i],cli); 776 cli.addMethod(mi); 777 } 778 779 Constructor [] constructors = cl.getConstructors(); 781 for(int i=0; i<constructors.length; i++) { 782 if ( ! ( isDefaultConstructorAdded(cl) && 783 constructors[i].getParameterTypes().length == 0 ) ) { 784 cli.addConstructor(new ConstructorItem(constructors[i],cli)); 785 } 786 } 787 788 } catch (InvalidDelegateException e) { 789 logger.error("buildDefaultRTTI("+cl.getName()+"): "+e); 790 return null; 791 } catch (NoClassDefFoundError e) { 792 logger.error("buildDefaultRTTI("+cl.getName()+")",e); 793 throw e; 794 } 795 logger.debug( ">>> DONE Constructing RTTI infos for class "+cl.getName()+Strings.hash(cl)+ 796 " -> "+cli+Strings.hash(cli)); 797 return cli; 798 } 799 800 public void buildDefaultFieldRTTI(ClassItem cli) { 801 loggerlt.debug("constructing fields info for "+cli.getName()); 802 Class cl = cli.getActualClass(); 803 Collection fields = getDirectFieldAccess(cl).values(); 804 Iterator it = fields.iterator(); 805 while (it.hasNext()) { 806 Field f = (Field ) it.next(); 807 Class t = f.getType(); 809 FieldItem fi = null; 810 MethodItem mis[] = null; 811 Method m = null; 812 try { 813 if (RttiAC.isCollectionType(t)) 814 { 815 logger.debug(t.getName()+" -> "+f.getName()+ " is a collection"); 816 fi = new CollectionItem(f,cli); 817 } else { 818 logger.debug(f.getName()+ " is a field"); 819 fi = new FieldItem(f,cli); 820 } 821 } catch (InvalidDelegateException e) { 822 e.printStackTrace(); 823 } 824 cli.addField(fi); 825 } 826 Logger logger = Logger.getLogger("rtti."+cli.getName()); 827 logger.debug("extracting bytecoded info for "+cli.getName()); 828 logger.debug("methods "+cli.getAllMethods()); 829 Iterator methods = cli.getAllMethods().iterator(); 830 while (methods.hasNext()) { 831 MethodItem method = (MethodItem)methods.next(); 832 try { 833 logger.debug(" "+method.getFullName()); 834 AbstractMethodItem realMethod = method.getConcreteMethod(); 835 String key = realMethod.getOwningClass().getName()+"."+realMethod.getFullName(); 836 ClassInfo classinfo = getClassInfo(realMethod.getOwningClass().getName()); 837 MethodInfo methodinfo = classinfo.getMethodInfo(key); 838 if (methodinfo.accessedFields.size()>0) { 839 logger.debug(" accessed fields: "+methodinfo.accessedFields); 840 it = methodinfo.accessedFields.iterator(); 841 while (it.hasNext()) { 842 String fieldName = (String )it.next(); 843 FieldItem fi = cli.getField(fieldName); 844 method.addAccessedField(fi); 845 fi.addAccessingMethod(method); 846 } 847 } 848 if (methodinfo.returnedField!=null && methodinfo.isGetter) { 849 logger.debug(" returned field: "+ 850 methodinfo.returnedField); 851 FieldItem fi = cli.getField(methodinfo.returnedField); 852 method.setReturnedField(fi); 853 fi.setGetter(method); 854 } 855 if (methodinfo.collectionIndexArgument!=-1) { 856 logger.debug(" collectionIndexArgument : "+ 857 methodinfo.collectionIndexArgument); 858 method.setCollectionIndexArgument(methodinfo.collectionIndexArgument); 859 } 860 if (methodinfo.collectionItemArgument!=-1) { 861 logger.debug(" collectionItemArgument : "+ 862 methodinfo.collectionItemArgument); 863 method.setCollectionItemArgument(methodinfo.collectionItemArgument); 864 } 865 if (methodinfo.modifiedFields.size()>0) { 866 logger.debug(" modified fields: "+methodinfo.modifiedFields); 867 it = methodinfo.modifiedFields.iterator(); 868 while(it.hasNext()) { 869 String fieldName = (String )it.next(); 870 try { 871 FieldItem fi = cli.getField(fieldName); 872 method.addWrittenField(fi); 873 fi.addWritingMethod(method); 874 } catch (NoSuchFieldException e) { 875 } 878 } 879 } 880 if (methodinfo.setFields.size()==1) { 881 logger.debug(" set fields: "+methodinfo.setFields); 882 it = methodinfo.setFields.iterator(); 883 while(it.hasNext()) { 884 String fieldName = (String )it.next(); 885 FieldItem fi = cli.getField(fieldName); 886 method.setSetField(fi); 887 fi.setSetter(method); 888 } 889 } else if (methodinfo.setFields.size()>1) { 890 logger.warn( 891 cli.getName()+" sets more than one field: "+ 892 methodinfo.setFields); 893 } 894 if (methodinfo.addedCollections.size()>0) { 895 logger.debug(" added collections: "+ 896 methodinfo.addedCollections); 897 it = methodinfo.addedCollections.iterator(); 898 while(it.hasNext()) { 899 String fieldName = (String )it.next(); 900 CollectionItem ci = cli.getCollection(fieldName); 901 method.addAddedCollection(ci); 902 ci.addAddingMethod(method); 903 } 904 } 905 if (methodinfo.removedCollections.size()>0) { 906 logger.debug(" removed collections: "+ 907 methodinfo.removedCollections); 908 it = methodinfo.removedCollections.iterator(); 909 while(it.hasNext()) { 910 String fieldName = (String )it.next(); 911 CollectionItem ci = cli.getCollection(fieldName); 912 method.addRemovedCollection(ci); 913 ci.addRemovingMethod(method); 914 } 915 } 916 if (methodinfo.modifiedCollections.size()>0) { 917 logger.debug(" modified collections: "+ 918 methodinfo.modifiedCollections); 919 it = methodinfo.modifiedCollections.iterator(); 920 while(it.hasNext()) { 921 String fieldName = (String )it.next(); 922 CollectionItem ci = cli.getCollection(fieldName); 923 method.addModifiedCollection(ci); 924 ci.addWritingMethod(method); 925 } 926 } 927 if (method.getType()!=void.class && 928 methodinfo.invokedMethods.size()>0) { 929 logger.debug(" invoked methods: "+methodinfo.invokedMethods); 930 it = methodinfo.invokedMethods.iterator(); 931 while(it.hasNext()) { 932 InvokeInfo invokeInfo = (InvokeInfo)it.next(); 933 ClassItem invokedClass = getClass(invokeInfo.className); 934 try { 935 MethodItem invokedMethod = 936 invokedClass.getMethod(invokeInfo.method); 937 if (invokedMethod.getType()!=void.class) 938 invokedMethod.addDependentMethod(method); 939 } catch(Exception e) { 940 } 941 } 942 } 943 if (methodinfo.callSuper) { 944 ClassItem superClass = cli.getSuperclass(); 945 logger.debug(" calls super"); 946 if (superClass!=null) { 947 try { 948 MethodItem superMethod = 949 superClass.getMethod(method.getFullName()); 950 if (superMethod.isAdder()) { 951 CollectionItem[] addedCollections = 952 superMethod.getAddedCollections(); 953 logger.debug(" added collections: "+ 954 Arrays.asList(addedCollections)); 955 for (int i=0; i<addedCollections.length; i++) { 956 CollectionItem collection = 957 cli.getCollection(addedCollections[i].getName()); 958 method.addAddedCollection(collection); 959 collection.addAddingMethod(method); 960 } 961 } 962 if (superMethod.isRemover()) { 963 CollectionItem[] removedCollections = 964 superMethod.getRemovedCollections(); 965 logger.debug(" removed collections: "+ 966 Arrays.asList(removedCollections)); 967 for (int i=0; i<removedCollections.length; i++) { 968 CollectionItem collection = 969 cli.getCollection(removedCollections[i].getName()); 970 method.addRemovedCollection(collection); 971 collection.addRemovingMethod(method); 972 } 973 } 974 if (superMethod.hasModifiedCollections()) { 975 CollectionItem[] modifiedCollections = 976 method.getModifiedCollections(); 977 logger.debug(" modified collections: "+ 978 Arrays.asList(modifiedCollections)); 979 for (int i=0; i<modifiedCollections.length; i++) { 980 CollectionItem collection = 981 cli.getCollection(modifiedCollections[i].getName()); 982 method.addModifiedCollection(collection); 983 collection.addWritingMethod(method); 984 } 985 } 986 if (superMethod.isSetter()) { 987 FieldItem field = 988 cli.getField(superMethod.getSetField().getName()); 989 method.setSetField(field); 990 field.setSetter(method); 991 logger.debug(" set field: "+field); 992 } 993 if (superMethod.hasWrittenFields()) { 994 FieldItem[] writtenFields = 995 superMethod.getWrittenFields(); 996 for (int i=0; i<writtenFields.length; i++) { 997 FieldItem field = cli.getField(writtenFields[i].getName()); 998 method.addWrittenField(field); 999 field.addWritingMethod(method); 1000 } 1001 } 1002 } catch (NoSuchMethodException e) { 1003 if (!superClass.hasMethod(method.getName(),method.getParameterTypes())) 1007 logger.warn( 1008 "Method "+method.getFullName()+ 1009 " calls super but super class "+superClass.getName()+ 1010 " does not have a public method with that name"); 1011 } 1012 } else { 1013 logger.warn("Method "+method.getFullName()+ 1014 " calls super but class does not have a super class"); 1015 } 1016 } 1017 } catch (Exception e) { 1018 logger.error("Failed RTTI build for "+method,e); 1019 } 1020 } 1021 1022 ClassItem superClass = cli.getSuperclass(); 1024 if (superClass!=null) { 1025 Iterator i = superClass.getMixinMethods().iterator(); 1026 while (i.hasNext()) { 1027 MixinMethodItem method = (MixinMethodItem)i.next(); 1028 try { 1029 cli.addMethod(new MixinMethodItem((Method )method.getDelegate(),cli)); 1030 logger.debug("Adding inherited mixin method "+method.getFullName()); 1031 } catch(InvalidDelegateException e) { 1032 logger.error("Failed to add inherited mixin method "+ 1033 method.getFullName(),e); 1034 } 1035 } 1036 } 1037 } 1038 1039 1041 public Hashtable objects = new Hashtable (); 1042 1043 1045 public Hashtable names = new Hashtable (); 1046 1047 1057 public void register(String logicalName, Object object) { 1058 Object o = objects.get(logicalName); 1059 boolean result = true; 1060 if (o != null && !(object instanceof VirtualClassItem)) { 1061 throw new RuntimeException ("Class "+logicalName+" is already registered: "+o); 1062 } 1063 objects.put(logicalName, object); 1064 names.put(object, logicalName); 1065 } 1066 1067 1074 public void unregister(String logicalName) { 1075 if (objects.get(logicalName) == null) { 1076 return; 1077 } 1078 names.remove(objects.get(logicalName)); 1079 objects.remove(logicalName); 1080 } 1081 1082 1089 public boolean isRegistered(String logicalName) { 1090 if (names.contains(logicalName)) { 1091 return true; 1092 } 1093 return false; 1094 } 1095 1096 1106 public Object [] getClasses() { 1107 return objects.values().toArray(); 1108 } 1109 1110 1117 public Object [] getNames() { 1118 return names.values().toArray(); 1119 } 1120 1121 1135 public Object getObject(String logicalName) { 1136 if (logicalName == null) return null; 1137 return objects.get(logicalName); 1138 } 1139 1140 1152 public String getName (Object object) { 1153 if (object == null) { 1154 return null; 1155 } 1156 return (String )names.get(object); 1157 } 1158 1159 1165 public FieldItem getActualField(Object substance, FieldItem field) { 1166 return getClass(substance).getField(field.getName()); 1167 } 1168 1169 1172 public void dump() { 1173 Enumeration keys = objects.keys(); 1174 1175 System.out.println ( getClass().getName() + " dump:"); 1176 while (keys.hasMoreElements()) { 1177 String key = (String ) keys.nextElement(); 1178 System.out.println(" - " + key + " : " + objects.get( key ) ); 1179 } 1180 } 1181 1182 1183 public static Object instantiate(Class type, String value) { 1184 if (type==int.class) { 1185 type = Integer .class; 1186 } else if (type==float.class) { 1187 type = Float .class; 1188 } else if (type==double.class) { 1189 type = Double .class; 1190 } else if (type==boolean.class) { 1191 type = Boolean .class; 1192 } else if (type==byte.class) { 1193 type = Byte .class; 1194 } else if (type==char.class) { 1195 type = Character .class; 1196 } else if (type==long.class) { 1197 type = Long .class; 1198 } else if (type==short.class) { 1199 type = Short .class; 1200 } 1201 try { 1202 Constructor constructor = type.getConstructor(new Class [] {String .class}); 1203 return constructor.newInstance(new Object [] {value}); 1204 } catch (Exception e) { 1205 e.printStackTrace(); 1206 return null; 1207 } 1208 } 1209} 1210 | Popular Tags |