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.

AnnotationAccessFieldVar.java 6.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /* *******************************************************************
  2. * Copyright (c) 2008 Contributors
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License v 2.0
  6. * which accompanies this distribution and is available at
  7. * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
  8. *
  9. * Contributors:
  10. * Andy Clement initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.weaver.bcel;
  13. import java.util.List;
  14. import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
  15. import org.aspectj.apache.bcel.classfile.annotation.ElementValue;
  16. import org.aspectj.apache.bcel.classfile.annotation.EnumElementValue;
  17. import org.aspectj.apache.bcel.classfile.annotation.NameValuePair;
  18. import org.aspectj.apache.bcel.classfile.annotation.SimpleElementValue;
  19. import org.aspectj.apache.bcel.generic.InstructionFactory;
  20. import org.aspectj.apache.bcel.generic.InstructionList;
  21. import org.aspectj.apache.bcel.generic.Type;
  22. import org.aspectj.weaver.AnnotationAJ;
  23. import org.aspectj.weaver.Member;
  24. import org.aspectj.weaver.ResolvedMember;
  25. import org.aspectj.weaver.ResolvedType;
  26. import org.aspectj.weaver.Shadow;
  27. import org.aspectj.weaver.UnresolvedType;
  28. /**
  29. * An AnnotationAccessVar represents access to a particular annotation, whilst an AnnotationAccessFieldVar represents access to a
  30. * specific field of that annotation.
  31. *
  32. * @author Andy Clement
  33. */
  34. class AnnotationAccessFieldVar extends BcelVar {
  35. private AnnotationAccessVar annoAccessor;
  36. private ResolvedType annoFieldOfInterest;
  37. private String name;
  38. private int elementValueType;
  39. public AnnotationAccessFieldVar(AnnotationAccessVar aav, ResolvedType annoFieldOfInterest, String name) {
  40. super(annoFieldOfInterest, 0);
  41. this.annoAccessor = aav;
  42. this.name = name;
  43. String sig = annoFieldOfInterest.getSignature();
  44. if (sig.length() == 1) {
  45. switch (sig.charAt(0)) {
  46. case 'I':
  47. elementValueType = ElementValue.PRIMITIVE_INT;
  48. break;
  49. default:
  50. throw new IllegalStateException(sig);
  51. }
  52. } else if (sig.equals("Ljava/lang/String;")) {
  53. elementValueType = ElementValue.STRING;
  54. } else if (annoFieldOfInterest.isEnum()) {
  55. elementValueType = ElementValue.ENUM_CONSTANT;
  56. } else {
  57. throw new IllegalStateException(sig);
  58. }
  59. this.annoFieldOfInterest = annoFieldOfInterest;
  60. }
  61. @Override
  62. public void appendLoadAndConvert(InstructionList il, InstructionFactory fact, ResolvedType toType) {
  63. // Only possible to do annotation field value extraction at MethodExecution
  64. if (annoAccessor.getKind() != Shadow.MethodExecution) {
  65. return;
  66. }
  67. String annotationOfInterestSignature = annoAccessor.getType().getSignature();
  68. // So we have an entity that has an annotation on and within it is the value we want
  69. Member holder = annoAccessor.getMember();
  70. AnnotationAJ[] annos = holder.getAnnotations();
  71. for (AnnotationAJ anno : annos) {
  72. AnnotationGen annotation = ((BcelAnnotation) anno).getBcelAnnotation();
  73. boolean foundValueInAnnotationUsage = false;
  74. if (annotation.getTypeSignature().equals(annotationOfInterestSignature)) {
  75. ResolvedMember[] annotationFields = toType.getWorld()
  76. .resolve(UnresolvedType.forSignature(annotation.getTypeSignature())).getDeclaredMethods();
  77. // Check how many fields there are of the type we are looking for. If >1 then we'll need
  78. // to use the name to choose the right one
  79. int countOfType = 0;
  80. for (ResolvedMember annotationField : annotationFields) {
  81. if (annotationField.getType().equals(annoFieldOfInterest)) {
  82. countOfType++;
  83. }
  84. }
  85. // this block deals with an annotation that has actual values (i.e. not falling back to default values)
  86. List<NameValuePair> nvps = annotation.getValues();
  87. for (NameValuePair nvp : nvps) {
  88. // If multiple of the same type, match by name
  89. if (countOfType > 1) {
  90. if (!nvp.getNameString().equals(name)) {
  91. continue;
  92. }
  93. }
  94. ElementValue o = nvp.getValue();
  95. if (o.getElementValueType() != elementValueType) {
  96. continue;
  97. }
  98. if (o instanceof EnumElementValue) {
  99. EnumElementValue v = (EnumElementValue) o;
  100. String s = v.getEnumTypeString();
  101. ResolvedType rt = toType.getWorld().resolve(UnresolvedType.forSignature(s));
  102. if (rt.equals(toType)) {
  103. il.append(fact.createGetStatic(rt.getName(), v.getEnumValueString(), Type.getType(rt.getSignature())));
  104. foundValueInAnnotationUsage = true;
  105. }
  106. } else if (o instanceof SimpleElementValue) {
  107. SimpleElementValue v = (SimpleElementValue) o;
  108. switch (v.getElementValueType()) {
  109. case ElementValue.PRIMITIVE_INT:
  110. il.append(fact.createConstant(v.getValueInt()));
  111. foundValueInAnnotationUsage = true;
  112. break;
  113. case ElementValue.STRING:
  114. il.append(fact.createConstant(v.getValueString()));
  115. foundValueInAnnotationUsage = true;
  116. break;
  117. default:
  118. throw new IllegalStateException("NYI: Unsupported annotation value binding for " + o);
  119. }
  120. }
  121. if (foundValueInAnnotationUsage) {
  122. break;
  123. }
  124. }
  125. // this block deals with default values
  126. if (!foundValueInAnnotationUsage) {
  127. for (ResolvedMember annotationField : annotationFields) {
  128. if (countOfType > 1) {
  129. if (!annotationField.getName().equals(name)) {
  130. continue;
  131. }
  132. }
  133. if (!annotationField.getType().getSignature().equals(annoFieldOfInterest.getSignature())) {
  134. continue;
  135. }
  136. if (annotationField.getType().getSignature().equals("I")) {
  137. int ivalue = Integer.parseInt(annotationField.getAnnotationDefaultValue());
  138. il.append(fact.createConstant(ivalue));
  139. foundValueInAnnotationUsage = true;
  140. break;
  141. } else if (annotationField.getType().getSignature().equals("Ljava/lang/String;")) {
  142. String svalue = annotationField.getAnnotationDefaultValue();
  143. il.append(fact.createConstant(svalue));
  144. foundValueInAnnotationUsage = true;
  145. break;
  146. } else {
  147. String dvalue = annotationField.getAnnotationDefaultValue();
  148. // form will be LBLAHBLAHBLAH;X where X is the field within X
  149. String typename = dvalue.substring(0, dvalue.lastIndexOf(';') + 1);
  150. String field = dvalue.substring(dvalue.lastIndexOf(';') + 1);
  151. ResolvedType rt = toType.getWorld().resolve(UnresolvedType.forSignature(typename));
  152. il.append(fact.createGetStatic(rt.getName(), field, Type.getType(rt.getSignature())));
  153. foundValueInAnnotationUsage = true;
  154. break;
  155. }
  156. }
  157. }
  158. }
  159. if (foundValueInAnnotationUsage) {
  160. break;
  161. }
  162. }
  163. }
  164. @Override
  165. public void insertLoad(InstructionList il, InstructionFactory fact) {
  166. // Only possible to do annotation field value extraction at
  167. // MethodExecution
  168. if (annoAccessor.getKind() != Shadow.MethodExecution) {
  169. return;
  170. }
  171. appendLoadAndConvert(il, fact, annoFieldOfInterest);
  172. }
  173. @Override
  174. public String toString() {
  175. return super.toString();
  176. }
  177. }