You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TestJava5ReflectionBasedReferenceTypeDelegate.java 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /* *******************************************************************
  2. * Copyright (c) 2005-2017 Contributors.
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://eclipse.org/legal/epl-v10.html
  8. *
  9. * Contributors:
  10. * Andrew Clement Initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.weaver;
  13. import junit.framework.Test;
  14. import junit.framework.TestSuite;
  15. import java.lang.annotation.Retention;
  16. import java.lang.annotation.RetentionPolicy;
  17. import java.lang.reflect.Field;
  18. import org.aspectj.weaver.reflect.ReflectionBasedReferenceTypeDelegateTest;
  19. public class TestJava5ReflectionBasedReferenceTypeDelegate extends ReflectionBasedReferenceTypeDelegateTest {
  20. public static Test suite() {
  21. TestSuite suite = new TestSuite("TestJava5ReflectionBasedReferenceTypeDelegate");
  22. suite.addTestSuite(TestJava5ReflectionBasedReferenceTypeDelegate.class);
  23. return suite;
  24. }
  25. /**
  26. * Let's play about with a generic type and ensure we can work with it in a reflective world.
  27. */
  28. public void testResolveGeneric() {
  29. UnresolvedType collectionType = UnresolvedType.forName("java.util.Collection");
  30. world.resolve(collectionType).getRawType().resolve(world);
  31. ResolvedMember[] methods = world.resolve(collectionType).getDeclaredMethods();
  32. int i = -1;
  33. for (int j=0;j<methods.length;j++) {
  34. ResolvedMember method = methods[j];
  35. if (method.getName().equals("toArray") && method.getParameterSignature().equals("([TT;)")) {
  36. i = j;
  37. }
  38. }
  39. assertTrue("Couldn't find 'toArray' in the set of methods? ", i != -1);
  40. // String expectedSignature = "java.lang.Object[] java.util.Collection.toArray(java.lang.Object[])";
  41. String expectedSignature = "([Ljava/lang/Object;)[Ljava/lang/Object;";
  42. assertTrue("Expected signature of '" + expectedSignature + "' but it was '" + methods[i].getSignatureErased(), methods[i]
  43. .getSignatureErased().equals(expectedSignature));
  44. }
  45. /**
  46. * Can we resolve the dreaded Enum type...
  47. */
  48. public void testResolveEnum() {
  49. ResolvedType enumType = world.resolve("java.lang.Enum");
  50. assertTrue("Should be the raw type but is " + enumType.typeKind, enumType.isRawType());
  51. ResolvedType theGenericEnumType = enumType.getGenericType();
  52. assertTrue("Should have a type variable ", theGenericEnumType.getTypeVariables().length > 0);
  53. TypeVariable tv = theGenericEnumType.getTypeVariables()[0];
  54. String expected = "TypeVar E extends java.lang.Enum<E>";
  55. assertTrue("Type variable should be '" + expected + "' but is '" + tv + "'", tv.toString().equals(expected));
  56. }
  57. public void testResolveClass() {
  58. world.resolve("java.lang.Class").getGenericType();
  59. }
  60. public void testGenericInterfaceSuperclass_ReflectionWorldResolution() {
  61. UnresolvedType javaUtilMap = UnresolvedType.forName("java.util.Map");
  62. ReferenceType rawType = (ReferenceType) world.resolve(javaUtilMap);
  63. assertTrue("Should be the raw type ?!? " + rawType.getTypekind(), rawType.isRawType());
  64. ReferenceType genericType = (ReferenceType) rawType.getGenericType();
  65. assertTrue("Should be the generic type ?!? " + genericType.getTypekind(), genericType.isGenericType());
  66. ResolvedType rt = rawType.getSuperclass();
  67. assertTrue("Superclass for Map raw type should be Object but was " + rt, rt.equals(UnresolvedType.OBJECT));
  68. ResolvedType rt2 = genericType.getSuperclass();
  69. assertTrue("Superclass for Map generic type should be Object but was " + rt2, rt2.equals(UnresolvedType.OBJECT));
  70. }
  71. /**
  72. * This is testing the optimization in the reflective annotation finder to verify that if you only want runtime
  73. * annotation info then we use reflection and don't go digging through the classfile bytes.
  74. */
  75. public void testAnnotationFinderClassRetention() throws Exception {
  76. ResolvedType type = world.resolve(AnnoTesting.class.getName());
  77. ResolvedMember[] ms = type.getDeclaredMethods();
  78. int findMethod = findMethod("a", ms);
  79. ResolvedMember methodWithOnlyClassLevelAnnotation = ms[findMethod("a", ms)];
  80. ResolvedMember methodWithOnlyRuntimeLevelAnnotation = ms[findMethod("b", ms)];
  81. ResolvedMember methodWithClassAndRuntimeLevelAnnotations = ms[findMethod("c", ms)];
  82. ResolvedMember methodWithClassAndRuntimeLevelAnnotations2 = ms[findMethod("d", ms)];
  83. assertTrue(methodWithOnlyClassLevelAnnotation.hasAnnotation(world.resolve(AnnoClass.class.getName())));
  84. assertTrue(methodWithOnlyRuntimeLevelAnnotation.hasAnnotation(world.resolve(AnnoRuntime.class.getName())));
  85. // This is the tricky scenario.
  86. // When asking about the runtime level annotations it should not go digging into bcel
  87. assertTrue(methodWithClassAndRuntimeLevelAnnotations.hasAnnotation(world.resolve(AnnoRuntime.class.getName())));
  88. Field annotationsField = ResolvedMemberImpl.class.getDeclaredField("annotationTypes");
  89. annotationsField.setAccessible(true);
  90. ResolvedType[] annoTypes = (ResolvedType[])annotationsField.get(methodWithClassAndRuntimeLevelAnnotations);
  91. // Should only be the runtime one here
  92. assertEquals(1, annoTypes.length);
  93. // But when you do ask again and this time for class level, it should redo the unpack and pull both runtime and class out
  94. assertTrue(methodWithClassAndRuntimeLevelAnnotations.hasAnnotation(world.resolve(AnnoClass.class.getName())));
  95. annotationsField.setAccessible(true);
  96. annoTypes = (ResolvedType[])annotationsField.get(methodWithClassAndRuntimeLevelAnnotations);
  97. // Now both should be there
  98. assertEquals(2, annoTypes.length);
  99. assertTrue(methodWithClassAndRuntimeLevelAnnotations2.hasAnnotation(world.resolve(AnnoRuntime.class.getName())));
  100. // now ask for 'all annotations' via another route, this should reunpack and get them all
  101. ResolvedType[] annotations = methodWithClassAndRuntimeLevelAnnotations2.getAnnotationTypes();
  102. assertEquals(2,annotations.length);
  103. }
  104. @Retention(RetentionPolicy.CLASS)
  105. @interface AnnoClass {}
  106. @Retention(RetentionPolicy.RUNTIME)
  107. @interface AnnoRuntime {}
  108. class AnnoTesting {
  109. @AnnoClass
  110. public void a() {}
  111. @AnnoRuntime
  112. public void b() {}
  113. @AnnoClass @AnnoRuntime
  114. public void c() {}
  115. @AnnoClass @AnnoRuntime
  116. public void d() {}
  117. }
  118. }