1 8 package com.tc.backport175.bytecode; 9 10 import com.tc.backport175.Annotation; 11 import com.tc.backport175.bytecode.spi.BytecodeProvider; 13 import com.tc.backport175.proxy.ProxyFactory; 14 15 import com.tc.asm.AnnotationVisitor; 16 import com.tc.asm.Attribute; 17 import com.tc.asm.ClassAdapter; 18 import com.tc.asm.ClassReader; 19 import com.tc.asm.ClassVisitor; 20 import com.tc.asm.ClassWriter; 21 import com.tc.asm.FieldVisitor; 22 import com.tc.asm.MethodAdapter; 23 import com.tc.asm.MethodVisitor; 24 import com.tc.asm.Type; 25 26 import java.lang.ref.Reference ; 27 import java.lang.ref.WeakReference ; 28 import java.lang.reflect.Constructor ; 29 import java.lang.reflect.Field ; 30 import java.lang.reflect.Method ; 31 import java.util.Collection ; 32 import java.util.HashMap ; 33 import java.util.Iterator ; 34 import java.util.Map ; 35 import java.util.WeakHashMap ; 36 37 50 public class AnnotationReader { 51 52 private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0]; 53 private static final AnnotationElement.Annotation[] EMPTY_ANNOTATION_ELEMENT_ARRAY = 54 new AnnotationElement.Annotation[0]; 55 private static final String INIT_METHOD_NAME = "<init>"; 56 57 private static final Map CLASS_SPECIFIC_BYTECODE_PROVIDER = new WeakHashMap (); 58 private static BytecodeProvider BYTECODE_PROVIDER = new DefaultBytecodeProvider(); 59 60 63 private static final Map READERS = new WeakHashMap (); 64 65 private final ClassKey m_classKey; 66 67 81 private final Map m_classAnnotationElements = new HashMap (); 82 private final Map m_constructorAnnotationElements = new HashMap (); 83 private final Map m_methodAnnotationElements = new HashMap (); 84 private final Map m_fieldAnnotationElements = new HashMap (); 85 86 private final Map m_classAnnotationCache = new HashMap (); 87 private final Map m_constructorAnnotationCache = new HashMap (); 88 private final Map m_methodAnnotationCache = new HashMap (); 89 private final Map m_fieldAnnotationCache = new HashMap (); 90 91 98 public static void setDefaultBytecodeProvider(final BytecodeProvider bytecodeProvider) { 99 BYTECODE_PROVIDER = bytecodeProvider; 100 } 101 102 107 public static BytecodeProvider getDefaultBytecodeProvider() { 108 return BYTECODE_PROVIDER; 109 } 110 111 119 public static void setBytecodeProviderFor(final Class klass, final BytecodeProvider bytecodeProvider) { 120 setBytecodeProviderFor(klass.getName(), klass.getClassLoader(), bytecodeProvider); 121 } 122 123 132 public static void setBytecodeProviderFor(final String className, 133 final ClassLoader loader, 134 final BytecodeProvider bytecodeProvider) { 135 CLASS_SPECIFIC_BYTECODE_PROVIDER.put(new ClassKey(className, loader), bytecodeProvider); 136 } 137 138 144 public static BytecodeProvider getBytecodeProviderFor(final Class klass) { 145 return getBytecodeProviderFor(klass.getName(), klass.getClassLoader()); 146 } 147 148 155 public static BytecodeProvider getBytecodeProviderFor(final String className, final ClassLoader loader) { 156 BytecodeProvider bytecodeProvider = (BytecodeProvider) CLASS_SPECIFIC_BYTECODE_PROVIDER.get( 157 new ClassKey(className, loader) 158 ); 159 if (bytecodeProvider == null) { 160 return BYTECODE_PROVIDER; 161 } 162 return bytecodeProvider; 163 } 164 165 172 public static byte[] getBytecodeFor(final String className, final ClassLoader loader) throws Exception { 173 return getBytecodeProviderFor(className, loader).getBytecode(className, loader); 174 } 175 176 184 public static AnnotationReader getReaderFor(final Class klass) { 185 return getReaderFor(new ClassKey(klass.getName(), klass.getClassLoader())); 186 } 187 188 197 public static AnnotationReader getReaderFor(final String className, final ClassLoader loader) { 198 return getReaderFor(new ClassKey(className, loader)); 199 } 200 201 209 public static AnnotationReader getReaderFor(final ClassKey classKey) { 210 AnnotationReader reader; 211 Object value = READERS.get(classKey); 212 if (value == null) { 213 synchronized (READERS) { 214 reader = new AnnotationReader(classKey); 215 READERS.put(classKey, new WeakReference (reader)); } 217 } else { 218 reader = (AnnotationReader) ((Reference )value).get(); 219 if (reader == null) { synchronized (READERS) { 221 reader = new AnnotationReader(classKey); 222 READERS.put(classKey, new WeakReference (reader)); 223 } 224 } 225 } 226 return reader; 227 } 228 229 236 public static void refresh(final Class klass) { 237 AnnotationReader reader = getReaderFor(klass); 238 synchronized (reader) { 239 reader.refresh(); 240 } 241 } 242 243 251 public static void refresh(final String className, final ClassLoader loader) { 252 AnnotationReader reader = getReaderFor(className, loader); 253 synchronized (reader) { 254 reader.refresh(); 255 } 256 } 257 258 265 public static void refreshAll() { 266 for (Iterator it = READERS.values().iterator(); it.hasNext();) { 267 AnnotationReader reader = (AnnotationReader) ((Reference )it.next()).get(); 268 synchronized (reader) { 269 reader.refresh(); 270 } 271 } 272 } 273 274 281 public static String toJavaName(final String desc) { 282 return desc.substring(1, desc.length() - 1).replace('/', '.'); 283 } 284 285 291 public boolean isAnnotationPresent(final String annotationName) { 292 return m_classAnnotationElements.containsKey(annotationName); 293 } 294 295 301 public Annotation getAnnotation(final String annotationName) { 302 Object cachedAnnotation = m_classAnnotationCache.get(annotationName); 303 if (cachedAnnotation != null) { 304 return (Annotation) cachedAnnotation; 305 } else { 306 final Annotation annotation; 307 final AnnotationElement.Annotation annotationInfo = 308 (AnnotationElement.Annotation) m_classAnnotationElements.get(annotationName); 309 if (annotationInfo != null) { 310 annotation = ProxyFactory.newAnnotationProxy(annotationInfo, m_classKey.getClassLoader()); 311 m_classAnnotationCache.put(annotationName, annotation); 312 return annotation; 313 } else { 314 return null; 315 } 316 } 317 } 318 319 324 public Annotation[] getAnnotations() { 325 final Collection annotationNames = m_classAnnotationElements.keySet(); 326 if (annotationNames.isEmpty()) { 327 return EMPTY_ANNOTATION_ARRAY; 328 } 329 final Annotation[] annotations = new Annotation[annotationNames.size()]; 330 int i = 0; 331 for (Iterator iterator = annotationNames.iterator(); iterator.hasNext();) { 332 String annotationName = (String ) iterator.next(); 333 annotations[i++] = getAnnotation(annotationName); 334 } 335 return annotations; 336 } 337 338 345 public boolean isAnnotationPresent(final String annotationName, final Constructor constructor) { 346 final AnnotationReader.MemberKey key = AnnotationReader.MemberKey.newConstructorKey(constructor); 347 Object map = m_constructorAnnotationElements.get(key); 348 if (map != null) { 349 if (((Map ) map).containsKey(annotationName)) { 350 return true; 351 } 352 } 353 return false; 354 } 355 356 363 public Annotation getAnnotation(final String annotationName, final Constructor constructor) { 364 return getConstructorAnnotation(annotationName, MemberKey.newConstructorKey(constructor), constructor.getDeclaringClass().getClassLoader()); 365 } 366 367 375 public Annotation getConstructorAnnotation(final String annotationName, final String constructorDesc, final ClassLoader loader) { 376 return getConstructorAnnotation(annotationName, MemberKey.newConstructorKey(constructorDesc), loader); 377 } 378 379 387 private Annotation getConstructorAnnotation(final String annotationName, final MemberKey constructorKey, final ClassLoader loader) { 388 Map annotationMap = getConstructorAnnotationCacheFor(constructorKey); 389 Object cachedAnnotation = annotationMap.get(annotationName); 390 if (cachedAnnotation != null) { 391 return (Annotation) cachedAnnotation; 392 } 393 final Map annotations = (Map ) m_constructorAnnotationElements.get(constructorKey); 395 if (annotations == null) { 396 return null; 398 } 399 Object annotationElement = annotations.get(annotationName); 400 if (annotationElement != null) { 401 Annotation annotation = ProxyFactory.newAnnotationProxy( 402 (AnnotationElement.Annotation) annotationElement, 403 loader 404 ); 405 annotationMap.put(annotationName, annotation); 406 return annotation; 407 } 408 return null; 409 } 410 411 417 public Annotation[] getAnnotations(final Constructor constructor) { 418 final AnnotationReader.MemberKey key = AnnotationReader.MemberKey.newConstructorKey(constructor); 419 Object map = m_constructorAnnotationElements.get(key); 420 if (map != null) { 421 final Collection annotationNames = ((Map ) map).keySet(); 422 if (annotationNames.isEmpty()) { 423 return EMPTY_ANNOTATION_ARRAY; 424 } 425 final Annotation[] annotations = new Annotation[annotationNames.size()]; 426 int i = 0; 427 for (Iterator iterator = annotationNames.iterator(); iterator.hasNext();) { 428 String annotationName = (String ) iterator.next(); 429 annotations[i++] = getAnnotation(annotationName, constructor); 430 } 431 return annotations; 432 } else { 433 return EMPTY_ANNOTATION_ARRAY; 434 } 435 } 436 437 444 public boolean isAnnotationPresent(final String annotationName, final Method method) { 445 final AnnotationReader.MemberKey key = AnnotationReader.MemberKey.newMethodKey(method); 446 Object map = m_methodAnnotationElements.get(key); 447 if (map != null) { 448 if (((Map ) m_methodAnnotationElements.get(key)).containsKey(annotationName)) { 449 return true; 450 } 451 } 452 return false; 453 } 454 455 462 public Annotation getAnnotation(final String annotationName, final Method method) { 463 return getMethodAnnotation( 464 annotationName, 465 MemberKey.newMethodKey(method), 466 method.getDeclaringClass().getClassLoader() 467 ); 468 } 469 470 479 public Annotation getMethodAnnotation(final String annotationName, final String methodName, final String methodDesc, final ClassLoader loader) { 480 return getMethodAnnotation( 481 annotationName, 482 MemberKey.newMethodKey(methodName, methodDesc), 483 loader 484 ); 485 } 486 487 495 private Annotation getMethodAnnotation(final String annotationName, final MemberKey methodKey, final ClassLoader loader) { 496 Map annotationMap = getMethodAnnotationCacheFor(methodKey); 497 Object cachedAnnotation = annotationMap.get(annotationName); 498 if (cachedAnnotation != null) { 499 return (Annotation) cachedAnnotation; 500 } 501 final Map annotations = (Map ) m_methodAnnotationElements.get(methodKey); 503 if (annotations == null) { 504 return null; 506 } 507 Object annotationElement = annotations.get(annotationName); 508 if (annotationElement != null) { 509 Annotation annotation = ProxyFactory.newAnnotationProxy( 510 (AnnotationElement.Annotation) annotationElement, 511 loader 512 ); 513 annotationMap.put(annotationName, annotation); 514 return annotation; 515 } 516 return null; 517 } 518 519 525 public Annotation[] getAnnotations(final Method method) { 526 final AnnotationReader.MemberKey key = AnnotationReader.MemberKey.newMethodKey(method); 527 Object map = m_methodAnnotationElements.get(key); 528 if (map != null) { 529 final Collection annotationNames = ((Map ) map).keySet(); 530 if (annotationNames.isEmpty()) { 531 return EMPTY_ANNOTATION_ARRAY; 532 } 533 final Annotation[] annotations = new Annotation[annotationNames.size()]; 534 int i = 0; 535 for (Iterator iterator = annotationNames.iterator(); iterator.hasNext();) { 536 String annotationName = (String ) iterator.next(); 537 annotations[i++] = getAnnotation(annotationName, method); 538 } 539 return annotations; 540 } else { 541 return EMPTY_ANNOTATION_ARRAY; 542 } 543 } 544 545 552 public boolean isAnnotationPresent(final String annotationName, final Field field) { 553 final AnnotationReader.MemberKey key = AnnotationReader.MemberKey.newFieldKey(field); 554 Object map = m_fieldAnnotationElements.get(key); 555 if (map != null) { 556 if (((Map ) map).containsKey(annotationName)) { 557 return true; 558 } 559 } 560 return false; 561 } 562 563 570 public Annotation getAnnotation(final String annotationName, final Field field) { 571 return getFieldAnnotation( 572 annotationName, 573 MemberKey.newFieldKey(field), 574 field.getDeclaringClass().getClassLoader() 575 ); 576 } 577 578 587 public Annotation getFieldAnnotation(final String annotationName, final String fieldName, final String fieldDesc, final ClassLoader loader) { 588 return getFieldAnnotation( 589 annotationName, 590 MemberKey.newFieldKey(fieldName, fieldDesc), 591 loader 592 ); 593 } 594 595 603 private Annotation getFieldAnnotation(final String annotationName, final MemberKey fieldKey, final ClassLoader loader) { 604 Map annotationMap = getFieldAnnotationCacheFor(fieldKey); 605 Object cachedAnnotation = annotationMap.get(annotationName); 606 if (cachedAnnotation != null) { 607 return (Annotation) cachedAnnotation; 608 } 609 final Map annotations = (Map ) m_fieldAnnotationElements.get(fieldKey); 611 if (annotations == null) { 612 return null; 614 } 615 Object annotationElement = annotations.get(annotationName); 616 if (annotationElement != null) { 617 Annotation annotation = ProxyFactory.newAnnotationProxy( 618 (AnnotationElement.Annotation) annotationElement, 619 loader 620 ); 621 annotationMap.put(annotationName, annotation); 622 return annotation; 623 } 624 return null; 625 } 626 627 633 public Annotation[] getAnnotations(final Field field) { 634 final AnnotationReader.MemberKey key = AnnotationReader.MemberKey.newFieldKey(field); 635 Object map = m_fieldAnnotationElements.get(key); 636 if (map != null) { 637 final Collection annotationNames = ((Map ) map).keySet(); 638 if (annotationNames.isEmpty()) { 639 return EMPTY_ANNOTATION_ARRAY; 640 } 641 final Annotation[] annotations = new Annotation[annotationNames.size()]; 642 int i = 0; 643 for (Iterator iterator = annotationNames.iterator(); iterator.hasNext();) { 644 String annotationName = (String ) iterator.next(); 645 annotations[i++] = getAnnotation(annotationName, field); 646 } 647 return annotations; 648 } else { 649 return EMPTY_ANNOTATION_ARRAY; 650 } 651 } 652 653 659 public AnnotationElement.Annotation getAnnotationElement(final String annotationName) { 660 return (AnnotationElement.Annotation) m_classAnnotationElements.get(annotationName); 661 } 662 663 668 public AnnotationElement.Annotation[] getAnnotationElements() { 669 final Collection annotations = m_classAnnotationElements.values(); 670 if (annotations.isEmpty()) { 671 return EMPTY_ANNOTATION_ELEMENT_ARRAY; 672 } 673 return createAnnotationElementArray(annotations); 674 } 675 676 683 public boolean isConstructorAnnotationPresent(final String annotationName, final String desc) { 684 final AnnotationReader.MemberKey key = AnnotationReader.MemberKey.newConstructorKey(desc); 685 Object map = m_constructorAnnotationElements.get(key); 686 if (map != null) { 687 if (((Map ) map).containsKey(annotationName)) { 688 return true; 689 } 690 } 691 return false; 692 } 693 694 701 public AnnotationElement.Annotation getConstructorAnnotationElement(final String annotationName, final String desc) { 702 final AnnotationReader.MemberKey key = AnnotationReader.MemberKey.newConstructorKey(desc); 703 final Map annotations = (Map ) m_constructorAnnotationElements.get(key); 704 if (annotations == null) { 705 return null; 707 } 708 return (AnnotationElement.Annotation) annotations.get(annotationName); 709 } 710 711 717 public AnnotationElement.Annotation[] getConstructorAnnotationElements(final String desc) { 718 final AnnotationReader.MemberKey key = AnnotationReader.MemberKey.newConstructorKey(desc); 719 Object map = m_constructorAnnotationElements.get(key); 720 if (map != null) { 721 final Collection annotations = ((Map ) map).values(); 722 if (annotations.isEmpty()) { 723 return EMPTY_ANNOTATION_ELEMENT_ARRAY; 724 } 725 return createAnnotationElementArray(annotations); 726 } else { 727 return EMPTY_ANNOTATION_ELEMENT_ARRAY; 728 } 729 } 730 731 739 public boolean isMethodAnnotationPresent(final String annotationName, final String name, final String desc) { 740 final AnnotationReader.MemberKey key = AnnotationReader.MemberKey.newMethodKey(name, desc); 741 Object map = m_methodAnnotationElements.get(key); 742 if (map != null) { 743 if (((Map ) map).containsKey(annotationName)) { 744 return true; 745 } 746 } 747 return false; 748 } 749 750 758 public AnnotationElement.Annotation getMethodAnnotationElement(final String annotationName, 759 final String name, 760 final String desc) { 761 final AnnotationReader.MemberKey key = AnnotationReader.MemberKey.newMethodKey(name, desc); 762 final Map annotations = (Map ) m_methodAnnotationElements.get(key); 763 if (annotations == null) { 764 return null; 766 } 767 return (AnnotationElement.Annotation) annotations.get(annotationName); 768 } 769 770 777 public AnnotationElement.Annotation[] getMethodAnnotationElements(final String name, final String desc) { 778 final AnnotationReader.MemberKey key = AnnotationReader.MemberKey.newMethodKey(name, desc); 779 Object map = m_methodAnnotationElements.get(key); 780 if (map != null) { 781 final Collection annotations = ((Map ) m_methodAnnotationElements.get(key)).values(); 782 if (annotations.isEmpty()) { 783 return EMPTY_ANNOTATION_ELEMENT_ARRAY; 784 } 785 return createAnnotationElementArray(annotations); 786 } else { 787 return EMPTY_ANNOTATION_ELEMENT_ARRAY; 788 } 789 } 790 791 799 public boolean isFieldAnnotationPresent(final String annotationName, final String name, final String desc) { 800 final AnnotationReader.MemberKey key = AnnotationReader.MemberKey.newFieldKey(name, desc); 801 Object map = m_fieldAnnotationElements.get(key); 802 if (map != null) { 803 if (((Map ) map).containsKey(annotationName)) { 804 return true; 805 } 806 } 807 return false; 808 } 809 810 818 public AnnotationElement.Annotation getFieldAnnotationElement(final String annotationName, 819 final String name, 820 final String desc) { 821 final AnnotationReader.MemberKey key = AnnotationReader.MemberKey.newFieldKey(name, desc); 822 final Map annotations = (Map ) m_fieldAnnotationElements.get(key); 823 if (annotations == null) { 824 return null; 826 } 827 return (AnnotationElement.Annotation) annotations.get(annotationName); 828 } 829 830 837 public AnnotationElement.Annotation[] getFieldAnnotationElements(final String name, final String desc) { 838 final AnnotationReader.MemberKey key = AnnotationReader.MemberKey.newFieldKey(name, desc); 839 Object map = m_fieldAnnotationElements.get(key); 840 if (map != null) { 841 final Collection annotations = ((Map ) m_fieldAnnotationElements.get(key)).values(); 842 if (annotations.isEmpty()) { 843 return EMPTY_ANNOTATION_ELEMENT_ARRAY; 844 } 845 return createAnnotationElementArray(annotations); 846 } else { 847 return EMPTY_ANNOTATION_ELEMENT_ARRAY; 848 } 849 } 850 851 857 private AnnotationElement.Annotation[] createAnnotationElementArray(final Collection annotations) { 858 int i = 0; 859 final AnnotationElement.Annotation[] elementArray = new AnnotationElement.Annotation[annotations.size()]; 860 for (Iterator it = annotations.iterator(); it.hasNext();) { 861 elementArray[i++] = (AnnotationElement.Annotation) it.next(); 862 } 863 return elementArray; 864 } 865 866 872 private Map getConstructorAnnotationCacheFor(final MemberKey constructor) { 873 Map annotationMap = (Map ) m_constructorAnnotationCache.get(constructor); 874 if (annotationMap == null) { 875 annotationMap = new HashMap (); 876 m_constructorAnnotationCache.put(constructor, annotationMap); 877 } 878 return annotationMap; 879 } 880 881 887 private Map getMethodAnnotationCacheFor(final MemberKey method) { 888 Map annotationMap = (Map ) m_methodAnnotationCache.get(method); 889 if (annotationMap == null) { 890 annotationMap = new HashMap (); 891 m_methodAnnotationCache.put(method, annotationMap); 892 } 893 return annotationMap; 894 } 895 896 902 private Map getFieldAnnotationCacheFor(final MemberKey field) { 903 Map annotationMap = (Map ) m_fieldAnnotationCache.get(field); 904 if (annotationMap == null) { 905 annotationMap = new HashMap (); 906 m_fieldAnnotationCache.put(field, annotationMap); 907 } 908 return annotationMap; 909 } 910 911 916 private void refresh() { 917 m_classAnnotationElements.clear(); 918 m_constructorAnnotationElements.clear(); 919 m_methodAnnotationElements.clear(); 920 m_fieldAnnotationElements.clear(); 921 m_classAnnotationCache.clear(); 922 m_constructorAnnotationCache.clear(); 923 m_methodAnnotationCache.clear(); 924 m_fieldAnnotationCache.clear(); 925 AnnotationDefaults.refresh(m_classKey); 926 parse(m_classKey); 927 } 928 929 934 private void parse(final ClassKey classKey) { 935 final String className = classKey.getName(); 936 final ClassLoader loader = classKey.getClassLoader(); 937 final byte[] bytes; 938 try { 939 bytes = getBytecodeFor(className, loader); 940 } catch (Exception e) { 941 e.printStackTrace(); 942 return; 943 } 947 ClassReader classReader = new ClassReader(bytes); 948 ClassWriter writer = new ClassWriter(true); 949 classReader.accept(new AnnotationRetrievingVisitor(writer), false); 950 } 951 952 957 private AnnotationReader(final ClassKey classKey) { 958 if (classKey == null) { 959 throw new IllegalArgumentException ("class info can not be null"); 960 } 961 m_classKey = classKey; 962 parse(classKey); 963 } 964 965 970 private class AnnotationRetrievingVisitor extends ClassAdapter { 971 972 public AnnotationRetrievingVisitor(final ClassVisitor cv) { 973 super(cv); 974 } 975 976 public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { 977 cv.visitAnnotation(desc, visible); 978 String annotationClassName = toJavaName(desc); 979 final AnnotationElement.Annotation annotation = new AnnotationElement.Annotation(annotationClassName); 980 m_classAnnotationElements.put(annotationClassName, annotation); 981 return createAnnotationVisitor(annotation); 982 } 983 984 public FieldVisitor visitField(final int access, 985 final String name, 986 final String desc, 987 final String signature, 988 final Object value) { 989 final FieldVisitor visitor = cv.visitField(access, name, desc, signature, value); 990 991 final MemberKey key = new MemberKey(name, desc); 992 return new AnnotationRetrievingFieldVisitor(key, visitor, AnnotationReader.this); 993 } 994 995 public MethodVisitor visitMethod(final int access, 996 final String name, 997 final String desc, 998 final String signature, 999 final String [] exceptions) { 1000 MethodVisitor visitor = cv.visitMethod(access, name, desc, signature, exceptions); 1001 1002 final MemberKey key = new MemberKey(name, desc); 1003 if (name.equals(INIT_METHOD_NAME)) { 1004 return new AnnotationRetrievingConstructorVisitor(visitor, key, AnnotationReader.this); 1005 } else { 1006 return new AnnotationRetrievingMethodVisitor(visitor, key, AnnotationReader.this); 1007 } 1008 } 1009 1010 } 1011 1012 1020 public AnnotationVisitor createAnnotationVisitor(final AnnotationElement.Annotation annotation) { 1021 return new AnnotationBuilderVisitor(annotation, m_classKey.getClassLoader(), annotation.getInterfaceName()); 1022 } 1024 1025 private static final class AnnotationRetrievingConstructorVisitor extends MethodAdapter { 1026 private final MemberKey key; 1027 private final AnnotationReader reader; 1028 1029 private AnnotationRetrievingConstructorVisitor(MethodVisitor mv, MemberKey key, AnnotationReader reader) { 1030 super(mv); 1031 this.key = key; 1032 this.reader = reader; 1033 } 1034 1035 public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { 1036 final String className = toJavaName(desc); 1037 final AnnotationElement.Annotation annotation = new AnnotationElement.Annotation(className); 1038 if (reader.m_constructorAnnotationElements.containsKey(key)) { 1039 ((Map ) reader.m_constructorAnnotationElements.get(key)).put(className, annotation); 1040 } else { 1041 final Map annotations = new HashMap (); 1042 annotations.put(className, annotation); 1043 reader.m_constructorAnnotationElements.put(key, annotations); 1044 } 1045 return reader.createAnnotationVisitor(annotation); 1046 } 1047 } 1048 1049 private static final class AnnotationRetrievingMethodVisitor extends MethodAdapter { 1050 private final MemberKey key; 1051 private final AnnotationReader reader; 1052 1053 private AnnotationRetrievingMethodVisitor(MethodVisitor mv, MemberKey key, AnnotationReader reader) { 1054 super(mv); 1055 this.key = key; 1056 this.reader = reader; 1057 } 1058 1059 public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { 1060 String className = toJavaName(desc); 1061 final AnnotationElement.Annotation annotation = new AnnotationElement.Annotation(className); 1062 if (reader.m_methodAnnotationElements.containsKey(key)) { 1063 ((Map ) reader.m_methodAnnotationElements.get(key)).put(className, annotation); 1064 } else { 1065 final Map annotations = new HashMap (); 1066 annotations.put(className, annotation); 1067 reader.m_methodAnnotationElements.put(key, annotations); 1068 } 1069 return reader.createAnnotationVisitor(annotation); 1070 } 1071 } 1072 1073 private static final class AnnotationRetrievingFieldVisitor implements FieldVisitor { 1074 private final MemberKey key; 1075 private final FieldVisitor visitor; 1076 private final AnnotationReader reader; 1077 1078 private AnnotationRetrievingFieldVisitor(MemberKey key, FieldVisitor visitor, AnnotationReader reader) { 1079 this.key = key; 1080 this.visitor = visitor; 1081 this.reader = reader; 1082 } 1083 1084 public AnnotationVisitor visitAnnotation(final String desc, boolean visible) { 1085 final String className = toJavaName(desc); 1086 final AnnotationElement.Annotation annotation = new AnnotationElement.Annotation(className); 1087 if (reader.m_fieldAnnotationElements.containsKey(key)) { 1088 ((Map ) reader.m_fieldAnnotationElements.get(key)).put(className, annotation); 1089 } else { 1090 final Map annotations = new HashMap (); 1091 annotations.put(className, annotation); 1092 reader.m_fieldAnnotationElements.put(key, annotations); 1093 } 1094 return reader.createAnnotationVisitor(annotation); 1095 } 1096 1097 public void visitAttribute(final Attribute attribute) { 1098 visitor.visitAttribute(attribute); 1099 } 1100 1101 public void visitEnd() { 1102 visitor.visitEnd(); 1103 } 1104 } 1105 1106 1107 static class AnnotationBuilderVisitor implements AnnotationVisitor { 1108 1109 private final AnnotationElement.NestedAnnotationElement m_nestedAnnotationElement; 1110 1111 1114 private final ClassLoader m_loader; 1115 1116 1120 private final String m_annotationClassName; 1121 1122 public AnnotationBuilderVisitor(final AnnotationElement.NestedAnnotationElement annotation, 1123 final ClassLoader loader, 1124 final String annotationClassName) { 1125 m_nestedAnnotationElement = annotation; 1126 m_loader = loader; 1127 m_annotationClassName = annotationClassName; 1128 } 1129 1130 public void visit(final String name, final Object value) { 1131 if (value instanceof Type) { 1132 m_nestedAnnotationElement.addElement(name, value); 1134 } else { 1135 if (value.getClass().isArray()) { 1137 handlePrimitiveArrayValue(value, name); 1139 } else { 1140 m_nestedAnnotationElement.addElement(name, value); 1142 } 1143 } 1144 } 1145 1146 public void visitEnum(final String name, final String desc, final String value) { 1147 m_nestedAnnotationElement.addElement(name, new AnnotationElement.Enum(desc, value)); 1148 } 1149 1150 public AnnotationVisitor visitAnnotation(final String name, final String desc) { 1151 String className = toJavaName(desc); 1152 AnnotationElement.NestedAnnotationElement annotation = new AnnotationElement.Annotation(className); 1153 m_nestedAnnotationElement.addElement(name, annotation); 1154 return new AnnotationBuilderVisitor(annotation, m_loader, className); } 1156 1157 public AnnotationVisitor visitArray(final String name) { 1158 AnnotationElement.NestedAnnotationElement array = new AnnotationElement.Array(); 1159 m_nestedAnnotationElement.addElement(name, array); 1160 return new AnnotationBuilderVisitor(array, m_loader, null); 1161 } 1162 1163 public void visitEnd() { 1164 if (m_annotationClassName != null) { 1166 AnnotationElement.Annotation defaults = AnnotationDefaults.getDefaults(m_annotationClassName, m_loader); 1167 AnnotationElement.Annotation annotation = (AnnotationElement.Annotation) m_nestedAnnotationElement; 1168 for (Iterator iterator = defaults.getElements().iterator(); iterator.hasNext();) { 1169 AnnotationElement.NamedValue defaultedElement = (AnnotationElement.NamedValue) iterator.next(); 1170 annotation.mergeDefaultedElement(defaultedElement); 1171 } 1172 } 1173 } 1174 1175 1181 private void handlePrimitiveArrayValue(final Object value, final String name) { 1182 if (value.getClass().getComponentType().isPrimitive()) { 1183 if (value instanceof String []) { 1185 m_nestedAnnotationElement.addElement(name, value); 1187 } else { 1188 AnnotationElement.NestedAnnotationElement arrayElement = new AnnotationElement.Array(); 1189 if (value instanceof int[]) { 1191 int[] array = (int[]) value; 1192 for (int i = 0; i < array.length; i++) { 1193 arrayElement.addElement(null, new Integer (array[i])); 1194 } 1195 } else if (value instanceof long[]) { 1196 long[] array = (long[]) value; 1197 for (int i = 0; i < array.length; i++) { 1198 arrayElement.addElement(null, new Long (array[i])); 1199 } 1200 } else if (value instanceof short[]) { 1201 short[] array = (short[]) value; 1202 for (int i = 0; i < array.length; i++) { 1203 arrayElement.addElement(null, new Short (array[i])); 1204 } 1205 } else if (value instanceof float[]) { 1206 float[] array = (float[]) value; 1207 for (int i = 0; i < array.length; i++) { 1208 arrayElement.addElement(null, new Float (array[i])); 1209 } 1210 } else if (value instanceof double[]) { 1211 double[] array = (double[]) value; 1212 for (int i = 0; i < array.length; i++) { 1213 arrayElement.addElement(null, new Double (array[i])); 1214 } 1215 } else if (value instanceof boolean[]) { 1216 boolean[] array = (boolean[]) value; 1217 for (int i = 0; i < array.length; i++) { 1218 arrayElement.addElement(null, new Boolean (array[i])); 1219 } 1220 } else if (value instanceof byte[]) { 1221 byte[] array = (byte[]) value; 1222 for (int i = 0; i < array.length; i++) { 1223 arrayElement.addElement(null, new Byte (array[i])); 1224 } 1225 } else if (value instanceof char[]) { 1226 char[] array = (char[]) value; 1227 for (int i = 0; i < array.length; i++) { 1228 arrayElement.addElement(null, new Character (array[i])); 1229 } 1230 } 1231 m_nestedAnnotationElement.addElement(name, arrayElement); 1232 } 1233 } else { 1234 m_nestedAnnotationElement.addElement(name, value); 1235 } 1236 } 1237 } 1238 1239 1246 public static class ClassKey { 1247 private final String m_name; 1248 private final WeakReference m_loaderRef; 1249 1250 public ClassKey(final String name, final ClassLoader loader) { 1251 m_name = name.replace('.', '/'); 1252 m_loaderRef = new WeakReference (loader); 1253 } 1254 1255 public String getName() { 1256 return m_name; 1257 } 1258 1259 public ClassLoader getClassLoader() { 1260 return (ClassLoader ) m_loaderRef.get(); 1261 } 1262 1263 public boolean equals(Object o) { 1264 if (this == o) { 1265 return true; 1266 } 1267 if (!(o instanceof ClassKey)) { 1268 return false; 1269 } 1270 final ClassKey classKey = (ClassKey) o; 1271 ClassLoader loader1 = (ClassLoader ) m_loaderRef.get(); 1272 ClassLoader loader2 = (ClassLoader ) classKey.m_loaderRef.get(); 1273 if (loader1 != null ? !loader1.equals(loader2) : loader2 != null) { 1274 return false; 1275 } 1276 if (m_name != null ? !m_name.equals(classKey.m_name) : classKey.m_name != null) { 1277 return false; 1278 } 1279 return true; 1280 } 1281 1282 public int hashCode() { 1283 int result; 1284 result = (m_name != null ? m_name.hashCode() : 0); 1285 ClassLoader loader = (ClassLoader ) m_loaderRef.get(); 1286 result = 29 * result + (loader != null ? loader.hashCode() : 0); 1287 return result; 1288 } 1289 } 1290 1291 1298 public static class MemberKey { 1299 private final String m_name; 1300 private final String m_desc; 1301 1302 public static MemberKey newConstructorKey(final Constructor method) { 1303 return new MemberKey(INIT_METHOD_NAME, SignatureHelper.getConstructorSignature(method)); 1304 } 1305 1306 public static MemberKey newConstructorKey(final String desc) { 1307 return new MemberKey(INIT_METHOD_NAME, desc); 1308 } 1309 1310 public static MemberKey newMethodKey(final Method method) { 1311 return new MemberKey(method.getName(), SignatureHelper.getMethodSignature(method)); 1312 } 1313 1314 public static MemberKey newMethodKey(final String name, final String desc) { 1315 return new MemberKey(name, desc); 1316 } 1317 1318 public static MemberKey newFieldKey(final Field field) { 1319 return new MemberKey(field.getName(), SignatureHelper.getFieldSignature(field)); 1320 } 1321 1322 public static MemberKey newFieldKey(final String name, final String desc) { 1323 return new MemberKey(name, desc); 1324 } 1325 1326 public MemberKey(final String name, final String desc) { 1327 m_name = name; 1328 m_desc = desc; 1329 } 1330 1331 public boolean equals(Object o) { 1332 if (this == o) { 1333 return true; 1334 } 1335 if (!(o instanceof MemberKey)) { 1336 return false; 1337 } 1338 final MemberKey memberKey = (MemberKey) o; 1339 if (m_desc != null ? !m_desc.equals(memberKey.m_desc) : memberKey.m_desc != null) { 1340 return false; 1341 } 1342 if (m_name != null ? !m_name.equals(memberKey.m_name) : memberKey.m_name != null) { 1343 return false; 1344 } 1345 return true; 1346 } 1347 1348 public int hashCode() { 1349 int result; 1350 result = (m_name != null ? m_name.hashCode() : 0); 1351 result = 29 * result + (m_desc != null ? m_desc.hashCode() : 0); 1352 return result; 1353 } 1354 } 1355 1356 1359 private class TraceAnnotationVisitor implements AnnotationVisitor { 1360 public void visit(final String name, final Object value) { 1361 System.out.println(" NAMED-VALUE: " + name + "->" + value); 1362 } 1363 1364 public void visitEnum(final String name, final String desc, final String value) { 1365 System.out.println(" ENUM: " + name); 1366 } 1367 1368 public AnnotationVisitor visitAnnotation(final String name, final String desc) { 1369 System.out.println(" ANNOTATION: " + name); 1370 return new TraceAnnotationVisitor(); 1371 } 1372 1373 public AnnotationVisitor visitArray(final String name) { 1374 System.out.println(" ARRAY: " + name); 1375 return new TraceAnnotationVisitor(); 1376 } 1377 1378 public void visitEnd() { 1379 } 1380 } 1381} 1382 | Popular Tags |