Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

WildAnnotationTypePattern.java 16KB

pirms 15 gadiem
pirms 15 gadiem
pirms 12 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 14 gadiem
pirms 15 gadiem
pirms 14 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 14 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 14 gadiem
pirms 15 gadiem
pirms 12 gadiem
pirms 14 gadiem
pirms 15 gadiem
pirms 12 gadiem
pirms 15 gadiem
pirms 12 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 9 gadiem
pirms 12 gadiem
pirms 9 gadiem
pirms 12 gadiem
pirms 15 gadiem
pirms 9 gadiem
pirms 15 gadiem
pirms 12 gadiem
pirms 9 gadiem
pirms 12 gadiem
pirms 9 gadiem
pirms 12 gadiem
pirms 9 gadiem
pirms 12 gadiem
pirms 9 gadiem
pirms 12 gadiem
pirms 9 gadiem
pirms 12 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 12 gadiem
pirms 15 gadiem
pirms 12 gadiem
pirms 12 gadiem
pirms 12 gadiem
pirms 12 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 14 gadiem
pirms 15 gadiem
pirms 14 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 14 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 14 gadiem
pirms 15 gadiem
pirms 12 gadiem
pirms 15 gadiem
pirms 14 gadiem
pirms 15 gadiem
pirms 14 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 14 gadiem
pirms 15 gadiem
pirms 14 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 14 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 14 gadiem
pirms 15 gadiem
pirms 15 gadiem
pirms 14 gadiem
pirms 15 gadiem
pirms 14 gadiem
pirms 15 gadiem
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. /* *******************************************************************
  2. * Copyright (c) 2004 IBM Corporation.
  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. * ******************************************************************/
  10. package org.aspectj.weaver.patterns;
  11. import java.io.IOException;
  12. import java.util.HashMap;
  13. import java.util.Map;
  14. import java.util.Set;
  15. import org.aspectj.bridge.IMessage;
  16. import org.aspectj.bridge.MessageUtil;
  17. import org.aspectj.util.FuzzyBoolean;
  18. import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
  19. import org.aspectj.weaver.AnnotatedElement;
  20. import org.aspectj.weaver.BCException;
  21. import org.aspectj.weaver.CompressingDataOutputStream;
  22. import org.aspectj.weaver.ISourceContext;
  23. import org.aspectj.weaver.ResolvedMember;
  24. import org.aspectj.weaver.ResolvedType;
  25. import org.aspectj.weaver.UnresolvedType;
  26. import org.aspectj.weaver.VersionedDataInputStream;
  27. import org.aspectj.weaver.WeaverMessages;
  28. import org.aspectj.weaver.World;
  29. /**
  30. * @author colyer
  31. * @author Andy Clement
  32. */
  33. public class WildAnnotationTypePattern extends AnnotationTypePattern {
  34. private TypePattern typePattern;
  35. private boolean resolved = false;
  36. Map<String, String> annotationValues;
  37. public WildAnnotationTypePattern(TypePattern typePattern) {
  38. super();
  39. this.typePattern = typePattern;
  40. this.setLocation(typePattern.getSourceContext(), typePattern.start, typePattern.end);
  41. }
  42. public WildAnnotationTypePattern(TypePattern typePattern, Map<String, String> annotationValues) {
  43. super();
  44. this.typePattern = typePattern;
  45. this.annotationValues = annotationValues;
  46. // PVAL make the location be from start of type pattern to end of values
  47. this.setLocation(typePattern.getSourceContext(), typePattern.start, typePattern.end);
  48. }
  49. public TypePattern getTypePattern() {
  50. return typePattern;
  51. }
  52. /*
  53. * (non-Javadoc)
  54. *
  55. * @see org.aspectj.weaver.patterns.AnnotationTypePattern#matches(org.aspectj.weaver.AnnotatedElement)
  56. */
  57. @Override
  58. public FuzzyBoolean matches(AnnotatedElement annotated) {
  59. return matches(annotated, null);
  60. }
  61. /**
  62. * Resolve any annotation values specified, checking they are all well formed (valid names, valid values)
  63. *
  64. * @param annotationType the annotation type for which the values have been specified
  65. * @param scope the scope within which to resolve type references (eg. Color.GREEN)
  66. */
  67. protected void resolveAnnotationValues(ResolvedType annotationType, IScope scope) {
  68. if (annotationValues == null) {
  69. return;
  70. }
  71. // Check any values specified are OK:
  72. // - the value names are for valid annotation fields
  73. // - the specified values are of the correct type
  74. // - for enums, check the specified values can be resolved in the specified scope
  75. Map<String,String> replacementValues = new HashMap<>();
  76. Set<String> keys = annotationValues.keySet();
  77. ResolvedMember[] ms = annotationType.getDeclaredMethods();
  78. for (String k: keys) {
  79. String key = k;
  80. // a trailing ! indicates the the user expressed key!=value rather than key=value as a match constraint
  81. if (k.endsWith("!")) {
  82. key = key.substring(0, k.length() - 1);
  83. }
  84. String v = annotationValues.get(k);
  85. boolean validKey = false;
  86. for (ResolvedMember resolvedMember : ms) {
  87. if (resolvedMember.getName().equals(key) && resolvedMember.isAbstract()) {
  88. validKey = true;
  89. ResolvedType t = resolvedMember.getReturnType().resolve(scope.getWorld());
  90. if (t.isEnum()) {
  91. // value must be an enum reference X.Y
  92. int pos = v.lastIndexOf(".");
  93. if (pos == -1) {
  94. IMessage m = MessageUtil.error(
  95. WeaverMessages.format(WeaverMessages.INVALID_ANNOTATION_VALUE, v, "enum"), getSourceLocation());
  96. scope.getWorld().getMessageHandler().handleMessage(m);
  97. } else {
  98. String typename = v.substring(0, pos);
  99. ResolvedType rt = scope.lookupType(typename, this).resolve(scope.getWorld());
  100. v = rt.getSignature() + v.substring(pos + 1); // from 'Color.RED' to 'Lp/Color;RED'
  101. replacementValues.put(k, v);
  102. break;
  103. }
  104. } else if (t.isPrimitiveType()) {
  105. if (t.getSignature().equals("I")) {
  106. try {
  107. int value = Integer.parseInt(v);
  108. replacementValues.put(k, Integer.toString(value));
  109. break;
  110. } catch (NumberFormatException nfe) {
  111. IMessage m = MessageUtil.error(
  112. WeaverMessages.format(WeaverMessages.INVALID_ANNOTATION_VALUE, v, "int"),
  113. getSourceLocation());
  114. scope.getWorld().getMessageHandler().handleMessage(m);
  115. }
  116. } else if (t.getSignature().equals("F")) {
  117. try {
  118. float value = Float.parseFloat(v);
  119. replacementValues.put(k, Float.toString(value));
  120. break;
  121. } catch (NumberFormatException nfe) {
  122. IMessage m = MessageUtil.error(
  123. WeaverMessages.format(WeaverMessages.INVALID_ANNOTATION_VALUE, v, "float"),
  124. getSourceLocation());
  125. scope.getWorld().getMessageHandler().handleMessage(m);
  126. }
  127. } else if (t.getSignature().equals("Z")) {
  128. if (v.equalsIgnoreCase("true") || v.equalsIgnoreCase("false")) {
  129. // is it ok !
  130. } else {
  131. IMessage m = MessageUtil.error(
  132. WeaverMessages.format(WeaverMessages.INVALID_ANNOTATION_VALUE, v, "boolean"),
  133. getSourceLocation());
  134. scope.getWorld().getMessageHandler().handleMessage(m);
  135. }
  136. } else if (t.getSignature().equals("S")) {
  137. try {
  138. short value = Short.parseShort(v);
  139. replacementValues.put(k, Short.toString(value));
  140. break;
  141. } catch (NumberFormatException nfe) {
  142. IMessage m = MessageUtil.error(
  143. WeaverMessages.format(WeaverMessages.INVALID_ANNOTATION_VALUE, v, "short"),
  144. getSourceLocation());
  145. scope.getWorld().getMessageHandler().handleMessage(m);
  146. }
  147. } else if (t.getSignature().equals("J")) {
  148. try {
  149. replacementValues.put(k, Long.toString(Long.parseLong(v)));
  150. break;
  151. } catch (NumberFormatException nfe) {
  152. IMessage m = MessageUtil.error(
  153. WeaverMessages.format(WeaverMessages.INVALID_ANNOTATION_VALUE, v, "long"),
  154. getSourceLocation());
  155. scope.getWorld().getMessageHandler().handleMessage(m);
  156. }
  157. } else if (t.getSignature().equals("D")) {
  158. try {
  159. replacementValues.put(k, Double.toString(Double.parseDouble(v)));
  160. break;
  161. } catch (NumberFormatException nfe) {
  162. IMessage m = MessageUtil.error(
  163. WeaverMessages.format(WeaverMessages.INVALID_ANNOTATION_VALUE, v, "double"),
  164. getSourceLocation());
  165. scope.getWorld().getMessageHandler().handleMessage(m);
  166. }
  167. } else if (t.getSignature().equals("B")) {
  168. try {
  169. replacementValues.put(k, Byte.toString(Byte.parseByte(v)));
  170. break;
  171. } catch (NumberFormatException nfe) {
  172. IMessage m = MessageUtil.error(
  173. WeaverMessages.format(WeaverMessages.INVALID_ANNOTATION_VALUE, v, "byte"),
  174. getSourceLocation());
  175. scope.getWorld().getMessageHandler().handleMessage(m);
  176. }
  177. } else if (t.getSignature().equals("C")) {
  178. if (v.length() != 3) { // '?'
  179. IMessage m = MessageUtil.error(
  180. WeaverMessages.format(WeaverMessages.INVALID_ANNOTATION_VALUE, v, "char"),
  181. getSourceLocation());
  182. scope.getWorld().getMessageHandler().handleMessage(m);
  183. } else {
  184. replacementValues.put(k, v.substring(1, 2));
  185. break;
  186. }
  187. } else {
  188. throw new RuntimeException("Not implemented for " + t);
  189. }
  190. } else if (t.equals(ResolvedType.JL_STRING)) {
  191. // nothing to do, it will be OK
  192. } else if (t.equals(ResolvedType.JL_CLASS) || (t.isParameterizedOrGenericType() && t.getRawType().equals(ResolvedType.JL_CLASS))) {
  193. String typename = v.substring(0, v.lastIndexOf('.')); // strip off '.class'
  194. ResolvedType rt = scope.lookupType(typename, this).resolve(scope.getWorld());
  195. if (rt.isMissing()) {
  196. IMessage m = MessageUtil.error("Unable to resolve type '" + v + "' specified for value '" + k + "'",
  197. getSourceLocation());
  198. scope.getWorld().getMessageHandler().handleMessage(m);
  199. }
  200. replacementValues.put(k, rt.getSignature());
  201. break;
  202. } else {
  203. if (t.isAnnotation()) {
  204. if (v.contains("(")) {
  205. throw new RuntimeException(
  206. "Compiler limitation: annotation values can only currently be marker annotations (no values): "
  207. + v);
  208. }
  209. String typename = v.substring(1);
  210. ResolvedType rt = scope.lookupType(typename, this).resolve(scope.getWorld());
  211. if (rt.isMissing()) {
  212. IMessage m = MessageUtil.error(
  213. "Unable to resolve type '" + v + "' specified for value '" + k + "'", getSourceLocation());
  214. scope.getWorld().getMessageHandler().handleMessage(m);
  215. }
  216. replacementValues.put(k, rt.getSignature());
  217. break;
  218. // } else if (t.isArray()) {
  219. // Looks like {} aren't pseudotokens in the parser so they don't get through for our pointcut parser
  220. // // @Foo(value=[Foo.class])
  221. // String typename = v.substring(0, v.lastIndexOf('.')); // strip off '.class'
  222. // ResolvedType rt = scope.lookupType(typename, this).resolve(scope.getWorld());
  223. // if (rt.isMissing()) {
  224. // IMessage m = MessageUtil.error("Unable to resolve type '" + v + "' specified for value '" + k + "'",
  225. // getSourceLocation());
  226. // scope.getWorld().getMessageHandler().handleMessage(m);
  227. // }
  228. // replacementValues.put(k, rt.getSignature());
  229. } else {
  230. scope.message(MessageUtil.error(WeaverMessages.format(WeaverMessages.UNSUPPORTED_ANNOTATION_VALUE_TYPE, t), getSourceLocation()));
  231. replacementValues.put(k, "");
  232. }
  233. }
  234. }
  235. }
  236. if (!validKey) {
  237. IMessage m = MessageUtil.error(WeaverMessages.format(WeaverMessages.UNKNOWN_ANNOTATION_VALUE, annotationType, k),
  238. getSourceLocation());
  239. scope.getWorld().getMessageHandler().handleMessage(m);
  240. }
  241. }
  242. annotationValues.putAll(replacementValues);
  243. }
  244. @Override
  245. public FuzzyBoolean matches(AnnotatedElement annotated, ResolvedType[] parameterAnnotations) {
  246. if (!resolved) {
  247. throw new IllegalStateException("Can't match on an unresolved annotation type pattern");
  248. }
  249. if (annotationValues != null && !typePattern.hasFailedResolution()) {
  250. // PVAL improve this restriction, would allow '*(value=Color.RED)'
  251. throw new IllegalStateException("Cannot use annotationvalues with a wild annotation pattern");
  252. }
  253. if (isForParameterAnnotationMatch()) {
  254. if (parameterAnnotations != null && parameterAnnotations.length != 0) {
  255. for (ResolvedType parameterAnnotation : parameterAnnotations) {
  256. if (typePattern.matches(parameterAnnotation, TypePattern.STATIC).alwaysTrue()) {
  257. return FuzzyBoolean.YES;
  258. }
  259. }
  260. }
  261. } else {
  262. // matches if the type of any of the annotations on the AnnotatedElement is
  263. // matched by the typePattern.
  264. ResolvedType[] annTypes = annotated.getAnnotationTypes();
  265. if (annTypes != null && annTypes.length != 0) {
  266. for (ResolvedType annType : annTypes) {
  267. if (typePattern.matches(annType, TypePattern.STATIC).alwaysTrue()) {
  268. return FuzzyBoolean.YES;
  269. }
  270. }
  271. }
  272. }
  273. return FuzzyBoolean.NO;
  274. }
  275. /*
  276. * (non-Javadoc)
  277. *
  278. * @see org.aspectj.weaver.patterns.AnnotationTypePattern#resolve(org.aspectj.weaver.World)
  279. */
  280. @Override
  281. public void resolve(World world) {
  282. if (!resolved) {
  283. // attempt resolution - this helps with the Spring bug where they resolve() the pointcut in no scope (SPR-5307)
  284. if (typePattern instanceof WildTypePattern && (annotationValues == null || annotationValues.isEmpty())) {
  285. WildTypePattern wildTypePattern = (WildTypePattern) typePattern;
  286. String fullyQualifiedName = wildTypePattern.maybeGetCleanName();
  287. if (fullyQualifiedName != null && fullyQualifiedName.contains(".")) {
  288. ResolvedType resolvedType = world.resolve(UnresolvedType.forName(fullyQualifiedName));
  289. if (resolvedType != null && !resolvedType.isMissing()) {
  290. typePattern = new ExactTypePattern(resolvedType, false, false, null);
  291. }
  292. }
  293. }
  294. resolved = true;
  295. }
  296. }
  297. /**
  298. * This can modify in place, or return a new TypePattern if the type changes.
  299. */
  300. @Override
  301. public AnnotationTypePattern resolveBindings(IScope scope, Bindings bindings, boolean allowBinding) {
  302. if (!scope.getWorld().isInJava5Mode()) {
  303. scope.message(MessageUtil.error(WeaverMessages.format(WeaverMessages.ANNOTATIONS_NEED_JAVA5), getSourceLocation()));
  304. return this;
  305. }
  306. if (resolved) {
  307. return this;
  308. }
  309. this.typePattern = typePattern.resolveBindings(scope, bindings, false, false);
  310. resolved = true;
  311. if (typePattern instanceof ExactTypePattern) {
  312. ExactTypePattern et = (ExactTypePattern) typePattern;
  313. if (!et.getExactType().resolve(scope.getWorld()).isAnnotation()) {
  314. IMessage m = MessageUtil.error(
  315. WeaverMessages.format(WeaverMessages.REFERENCE_TO_NON_ANNOTATION_TYPE, et.getExactType().getName()),
  316. getSourceLocation());
  317. scope.getWorld().getMessageHandler().handleMessage(m);
  318. resolved = false;
  319. }
  320. ResolvedType annotationType = et.getExactType().resolve(scope.getWorld());
  321. resolveAnnotationValues(annotationType, scope);
  322. ExactAnnotationTypePattern eatp = new ExactAnnotationTypePattern(annotationType, annotationValues);
  323. eatp.copyLocationFrom(this);
  324. if (isForParameterAnnotationMatch()) {
  325. eatp.setForParameterAnnotationMatch();
  326. }
  327. return eatp;
  328. } else {
  329. return this;
  330. }
  331. }
  332. @Override
  333. public AnnotationTypePattern parameterizeWith(Map<String,UnresolvedType> typeVariableMap, World w) {
  334. WildAnnotationTypePattern ret = new WildAnnotationTypePattern(typePattern.parameterizeWith(typeVariableMap, w));
  335. ret.copyLocationFrom(this);
  336. ret.resolved = resolved;
  337. return ret;
  338. }
  339. private static final byte VERSION = 1; // rev if ser. form changes
  340. @Override
  341. public void write(CompressingDataOutputStream s) throws IOException {
  342. s.writeByte(AnnotationTypePattern.WILD);
  343. s.writeByte(VERSION);
  344. typePattern.write(s);
  345. writeLocation(s);
  346. s.writeBoolean(isForParameterAnnotationMatch());
  347. // PVAL
  348. if (annotationValues == null) {
  349. s.writeInt(0);
  350. } else {
  351. s.writeInt(annotationValues.size());
  352. Set<String> key = annotationValues.keySet();
  353. for (String k : key) {
  354. s.writeUTF(k);
  355. s.writeUTF(annotationValues.get(k));
  356. }
  357. }
  358. }
  359. public static AnnotationTypePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException {
  360. WildAnnotationTypePattern ret;
  361. byte version = s.readByte();
  362. if (version > VERSION) {
  363. throw new BCException("ExactAnnotationTypePattern was written by a newer version of AspectJ");
  364. }
  365. TypePattern t = TypePattern.read(s, context);
  366. ret = new WildAnnotationTypePattern(t);
  367. ret.readLocation(context, s);
  368. if (s.getMajorVersion() >= WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ160) {
  369. if (s.readBoolean()) {
  370. ret.setForParameterAnnotationMatch();
  371. }
  372. }
  373. if (s.getMajorVersion() >= WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ160M2) {
  374. int annotationValueCount = s.readInt();
  375. if (annotationValueCount > 0) {
  376. Map<String, String> aValues = new HashMap<>();
  377. for (int i = 0; i < annotationValueCount; i++) {
  378. String key = s.readUTF();
  379. String val = s.readUTF();
  380. aValues.put(key, val);
  381. }
  382. ret.annotationValues = aValues;
  383. }
  384. }
  385. return ret;
  386. }
  387. @Override
  388. public boolean equals(Object obj) {
  389. if (!(obj instanceof WildAnnotationTypePattern)) {
  390. return false;
  391. }
  392. WildAnnotationTypePattern other = (WildAnnotationTypePattern) obj;
  393. return other.typePattern.equals(typePattern)
  394. && this.isForParameterAnnotationMatch() == other.isForParameterAnnotationMatch()
  395. && (annotationValues == null ? other.annotationValues == null : annotationValues.equals(other.annotationValues));
  396. }
  397. @Override
  398. public int hashCode() {
  399. return (((17 + 37 * typePattern.hashCode()) * 37 + (isForParameterAnnotationMatch() ? 0 : 1)) * 37)
  400. + (annotationValues == null ? 0 : annotationValues.hashCode());
  401. }
  402. @Override
  403. public String toString() {
  404. return "@(" + typePattern.toString() + ")";
  405. }
  406. @Override
  407. public Object accept(PatternNodeVisitor visitor, Object data) {
  408. return visitor.visit(this, data);
  409. }
  410. public Object traverse(PatternNodeVisitor visitor, Object data) {
  411. Object ret = accept(visitor, data);
  412. if (this.typePattern != null)
  413. this.typePattern.traverse(visitor, ret);
  414. return ret;
  415. }
  416. }