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.

Java15PointcutExpressionTest.java 33KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685
  1. /* *******************************************************************
  2. * Copyright (c) 2005 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. * Adrian Colyer Initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.weaver.tools;
  13. import java.lang.annotation.Retention;
  14. import java.lang.annotation.RetentionPolicy;
  15. import java.lang.reflect.Method;
  16. import java.util.ArrayList;
  17. import java.util.Date;
  18. import java.util.HashSet;
  19. import java.util.Iterator;
  20. import java.util.List;
  21. import java.util.Set;
  22. import java.util.StringTokenizer;
  23. import org.aspectj.lang.annotation.Pointcut;
  24. import org.aspectj.weaver.ResolvedType;
  25. import org.aspectj.weaver.internal.tools.PointcutExpressionImpl;
  26. import org.aspectj.weaver.patterns.AbstractPatternNodeVisitor;
  27. import org.aspectj.weaver.patterns.AndAnnotationTypePattern;
  28. import org.aspectj.weaver.patterns.AnnotationPatternList;
  29. import org.aspectj.weaver.patterns.AnyAnnotationTypePattern;
  30. import org.aspectj.weaver.patterns.BindingAnnotationTypePattern;
  31. import org.aspectj.weaver.patterns.ExactAnnotationTypePattern;
  32. import org.aspectj.weaver.patterns.KindedPointcut;
  33. import org.aspectj.weaver.patterns.NotAnnotationTypePattern;
  34. import org.aspectj.weaver.patterns.OrAnnotationTypePattern;
  35. import org.aspectj.weaver.patterns.SignaturePattern;
  36. import org.aspectj.weaver.patterns.TypePattern;
  37. import org.aspectj.weaver.patterns.TypePatternList;
  38. import org.aspectj.weaver.patterns.WildAnnotationTypePattern;
  39. import test.A1AnnotatedType;
  40. import test.A2AnnotatedType;
  41. import junit.framework.Test;
  42. import junit.framework.TestCase;
  43. import junit.framework.TestSuite;
  44. /**
  45. * Test parameter pointcut parsing. Extended by Andy Clement to cover parameter annotation matching.
  46. *
  47. */
  48. public class Java15PointcutExpressionTest extends TestCase {
  49. public static Test suite() {
  50. TestSuite suite = new TestSuite("Java15PointcutExpressionTest");
  51. suite.addTestSuite(Java15PointcutExpressionTest.class);
  52. return suite;
  53. }
  54. private PointcutParser parser;
  55. private Method a;
  56. private Method b;
  57. private Method c;
  58. private Method d;
  59. /**
  60. * Parse some expressions and ensure we capture the parameter annotations and parameter type annotations correctly.
  61. * Buckle up, this will get complicated ;)
  62. */
  63. public void testParseParameterAnnotationExpressions() {
  64. PointcutParser p = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingSpecifiedClassloaderForResolution(this.getClass().getClassLoader());
  65. PointcutExpression pexpr = null;
  66. pexpr = p.parsePointcutExpression("execution(public void foo(@MA *))");
  67. checkParameterAnnotations(pexpr,0,null,"@MA","exact[@MA:t]");
  68. pexpr = p.parsePointcutExpression("execution(public void foo(@MA (*)))");
  69. checkParameterAnnotations(pexpr,0,"@MA",null,"exact[@MA:p]");
  70. pexpr = p.parsePointcutExpression("execution(public void foo(@MA @MB *))");
  71. checkParameterAnnotations(pexpr,0,null,"@MA @MB","(exact[@MA:t] and exact[@MB:t])");
  72. pexpr = p.parsePointcutExpression("execution(public void foo(@MA (@MB *)))");
  73. checkParameterAnnotations(pexpr,0,"@MA","@MB","(exact[@MA:p] and exact[@MB:t])");
  74. pexpr = p.parsePointcutExpression("execution(public void foo(@MA @MB (@MC *)))");
  75. checkParameterAnnotations(pexpr,0,"@MA @MB","@MC","((exact[@MA:p] and exact[@MB:p]) and exact[@MC:t])");
  76. pexpr = p.parsePointcutExpression("execution(public void foo(@MA (@MB @MC @MD *)))");
  77. checkParameterAnnotations(pexpr,0,"@MA","@MB @MC @MD","(exact[@MA:p] and ((exact[@MB:t] and exact[@MC:t]) and exact[@MD:t]))");
  78. pexpr = p.parsePointcutExpression("execution(public void foo(@(MA || MB) (@MC @MD *)))");
  79. checkParameterAnnotations(pexpr,0,null/*Should be MA MB */,"@MC @MD","(wild[(MA || MB)] and (exact[@MC:t] and exact[@MD:t]))"); // I dont think WildAnnotationTypePatterns work properly...
  80. pexpr = p.parsePointcutExpression("execution(public void foo(@MA (@MB *),(@MC *),@MD (*)))");
  81. checkParameterAnnotations(pexpr,0,"@MA","@MB","(exact[@MA:p] and exact[@MB:t])");
  82. checkParameterAnnotations(pexpr,1,null,"@MC","exact[@MC:t]");
  83. checkParameterAnnotations(pexpr,2,"@MD",null,"exact[@MD:p]");
  84. }
  85. public void testMatchingAnnotationValueExpressions() throws SecurityException, NoSuchMethodException {
  86. PointcutParser p = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingSpecifiedClassloaderForResolution(this.getClass().getClassLoader());
  87. PointcutExpression pexpr = null;
  88. ShadowMatch match = null;
  89. Method n = test.AnnoValues.class.getMethod("none",null);
  90. Method r = test.AnnoValues.class.getMethod("redMethod",null);
  91. Method g = test.AnnoValues.class.getMethod("greenMethod",null);
  92. Method b = test.AnnoValues.class.getMethod("blueMethod",null);
  93. Method d = test.AnnoValues.class.getMethod("defaultMethod",null);
  94. pexpr = p.parsePointcutExpression("execution(@test.A3(test.Color.RED) public void *(..))");
  95. assertTrue("Should match", pexpr.matchesMethodExecution(n).neverMatches()); // default value RED
  96. assertTrue("Should match", pexpr.matchesMethodExecution(r).alwaysMatches());
  97. assertTrue("Should not match", pexpr.matchesMethodExecution(g).neverMatches());
  98. assertTrue("Should not match", pexpr.matchesMethodExecution(b).neverMatches());
  99. assertTrue("Should match", pexpr.matchesMethodExecution(d).alwaysMatches());
  100. pexpr = p.parsePointcutExpression("execution(@test.A3(test.Color.GREEN) public void *(..))");
  101. assertTrue("Should not match", pexpr.matchesMethodExecution(n).neverMatches()); // default value RED
  102. assertTrue("Should not match", pexpr.matchesMethodExecution(r).neverMatches());
  103. assertTrue("Should match", pexpr.matchesMethodExecution(g).alwaysMatches());
  104. assertTrue("Should not match", pexpr.matchesMethodExecution(b).neverMatches());
  105. assertTrue("Should not match", pexpr.matchesMethodExecution(d).neverMatches());
  106. pexpr = p.parsePointcutExpression("execution(@test.A3(test.Color.BLUE) public void *(..))");
  107. assertTrue("Should not match", pexpr.matchesMethodExecution(n).neverMatches()); // default value RED
  108. assertTrue("Should not match", pexpr.matchesMethodExecution(r).neverMatches());
  109. assertTrue("Should not match", pexpr.matchesMethodExecution(g).neverMatches());
  110. assertTrue("Should match", pexpr.matchesMethodExecution(b).alwaysMatches());
  111. assertTrue("Should not match", pexpr.matchesMethodExecution(d).neverMatches());
  112. pexpr = p.parsePointcutExpression("execution(@test.A3 public void *(..))");
  113. assertTrue("Should match", pexpr.matchesMethodExecution(n).neverMatches()); // default value RED
  114. assertTrue("Should match", pexpr.matchesMethodExecution(r).alwaysMatches());
  115. assertTrue("Should match", pexpr.matchesMethodExecution(g).alwaysMatches());
  116. assertTrue("Should match", pexpr.matchesMethodExecution(b).alwaysMatches());
  117. assertTrue("Should match", pexpr.matchesMethodExecution(d).alwaysMatches());
  118. }
  119. /**
  120. * Test matching of pointcuts against expressions. A reflection world is being used on the backend here (not a Bcel one).
  121. */
  122. public void testMatchingParameterAnnotationExpressions() throws SecurityException, NoSuchMethodException {
  123. PointcutParser p = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingSpecifiedClassloaderForResolution(this.getClass().getClassLoader());
  124. PointcutExpression pexpr = null;
  125. ShadowMatch match = null;
  126. Method a = test.A.class.getMethod("a",new Class[] {String.class}); // public void a(String s) {}
  127. Method b = test.A.class.getMethod("b",new Class[] {String.class}); // public void b(@A1 String s) {}
  128. Method c = test.A.class.getMethod("c",new Class[] {String.class}); // public void c(@A1 @A2 String s) {}
  129. Method d = test.A.class.getMethod("d",new Class[] {String.class,String.class});// public void d(@A1 String s,@A2 String t) {}
  130. Method e = test.A.class.getMethod("e",new Class[] {A1AnnotatedType.class}); // public void e(A1AnnotatedType s) {}
  131. Method f = test.A.class.getMethod("f",new Class[] {A2AnnotatedType.class}); // public void f(A2AnnotatedType s) {}
  132. Method g = test.A.class.getMethod("g",new Class[] {A1AnnotatedType.class}); // public void g(@A2 A1AnnotatedType s) {}
  133. Method h = test.A.class.getMethod("h",new Class[] {A1AnnotatedType.class}); // public void h(@A1 A1AnnotatedType s) {}
  134. Method i = test.A.class.getMethod("i",new Class[] {A1AnnotatedType.class,String.class}); // public void i(A1AnnotatedType s,@A2 String t) {}
  135. Method j = test.A.class.getMethod("j",new Class[] {String.class}); // public void j(@A1 @A2 String s) {}
  136. pexpr = p.parsePointcutExpression("execution(public void *(@test.A1 *))");
  137. assertTrue("Should not match", pexpr.matchesMethodExecution(a).neverMatches());
  138. assertTrue("Should not match", pexpr.matchesMethodExecution(b).neverMatches());
  139. assertTrue("Should not match", pexpr.matchesMethodExecution(c).neverMatches());
  140. pexpr = p.parsePointcutExpression("execution(public void *(@test.A1 (*)))");
  141. assertTrue("Should not match", pexpr.matchesMethodExecution(a).neverMatches());
  142. assertTrue("Should match", pexpr.matchesMethodExecution(b).alwaysMatches());
  143. assertTrue("Should match", pexpr.matchesMethodExecution(c).alwaysMatches());
  144. pexpr = p.parsePointcutExpression("execution(public void *(@test.A1 *))");
  145. assertTrue("Should match", pexpr.matchesMethodExecution(e).alwaysMatches());
  146. assertTrue("Should not match", pexpr.matchesMethodExecution(f).neverMatches());
  147. assertTrue("Should match", pexpr.matchesMethodExecution(g).alwaysMatches());
  148. assertTrue("Should match", pexpr.matchesMethodExecution(h).alwaysMatches());
  149. pexpr = p.parsePointcutExpression("execution(public void *(@test.A1 (*)))");
  150. assertTrue("Should not match", pexpr.matchesMethodExecution(e).neverMatches());
  151. assertTrue("Should not match", pexpr.matchesMethodExecution(f).neverMatches());
  152. assertTrue("Should not match", pexpr.matchesMethodExecution(g).neverMatches());
  153. assertTrue("Should match", pexpr.matchesMethodExecution(h).alwaysMatches());
  154. pexpr = p.parsePointcutExpression("execution(public void *(@(test.A1 || test.A2) (*)))");
  155. assertTrue("Should not match", pexpr.matchesMethodExecution(a).neverMatches());
  156. assertTrue("Should match", pexpr.matchesMethodExecution(b).alwaysMatches());
  157. assertTrue("Should match", pexpr.matchesMethodExecution(c).alwaysMatches());
  158. assertTrue("Should match", pexpr.matchesMethodExecution(g).alwaysMatches());
  159. assertTrue("Should match", pexpr.matchesMethodExecution(h).alwaysMatches());
  160. pexpr = p.parsePointcutExpression("execution(public void *(@(test.A1 && test.A2) (*),..))");
  161. assertTrue("Should not match", pexpr.matchesMethodExecution(a).neverMatches());
  162. assertTrue("Should not match", pexpr.matchesMethodExecution(b).neverMatches());
  163. assertTrue("Should not match", pexpr.matchesMethodExecution(c).neverMatches());
  164. assertTrue("Should not match", pexpr.matchesMethodExecution(g).neverMatches());
  165. assertTrue("Should not match", pexpr.matchesMethodExecution(h).neverMatches());
  166. // assertTrue("Should match", pexpr.matchesMethodExecution(j).alwaysMatches()); // should match but does not, broken implementation, old bug - see WildAnnotationTypePattern.match
  167. }
  168. private void checkParameterAnnotations(PointcutExpression pe,int parameterNumber,String expectedParameterAnnotations,String expectedParameterTypeAnnotations,String expectedNodeStructure) {
  169. org.aspectj.weaver.patterns.Pointcut p = ((PointcutExpressionImpl)pe).getUnderlyingPointcut();
  170. KindedPointcut kindedP = (KindedPointcut)p;
  171. SignaturePattern sp = kindedP.getSignature();
  172. TypePatternList tpl = sp.getParameterTypes();
  173. TypePattern[] tps = tpl.getTypePatterns();
  174. // A visitor over the annotation pattern for the parameter will break it down into parameter vs parameter type annotations
  175. MyPatternNodeVisitor mpnv = new MyPatternNodeVisitor();
  176. tps[parameterNumber].getAnnotationPattern().accept(mpnv,null);
  177. if (expectedNodeStructure==null) {
  178. // The caller hasn't worked it out yet!!
  179. System.out.println(mpnv.getStringRepresentation());
  180. } else if (!mpnv.getStringRepresentation().equals(expectedNodeStructure)) {
  181. System.out.println(mpnv.getStringRepresentation());
  182. fail("Expected annotation pattern node structure for expression "+pe.getPointcutExpression()+
  183. " was '"+expectedNodeStructure+"' but it turned out to be '"+mpnv.getStringRepresentation()+"'");
  184. }
  185. String annotationTypePattern = tps[parameterNumber].getAnnotationPattern().toString();
  186. // parameter type annotation checking
  187. Set<String> expected = new HashSet<String>();
  188. expected.addAll(mpnv.getParameterTypeAnnotations());
  189. StringTokenizer st = new StringTokenizer(expectedParameterTypeAnnotations==null?"":expectedParameterTypeAnnotations);
  190. while (st.hasMoreTokens()) {
  191. String nextToken = st.nextToken();
  192. if (!expected.contains(nextToken))
  193. fail("In pointcut expression "+pe.getPointcutExpression()+" parameter "+parameterNumber+". The annotation type pattern did not include parameter type annotation "+nextToken+". It's full set was "+mpnv.getParameterTypeAnnotations());
  194. expected.remove(nextToken);
  195. }
  196. if (expected.size()>0) { // we have excess ones!
  197. StringBuffer excessTokens = new StringBuffer();
  198. for (Iterator iterator = expected.iterator(); iterator.hasNext();) {
  199. String string = (String) iterator.next();
  200. excessTokens.append(string).append(" ");
  201. }
  202. fail("In pointcut expression "+pe.getPointcutExpression()+" parameter "+parameterNumber+". The annotation type pattern has these unexpected parameter type annotations "+excessTokens.toString());
  203. }
  204. // parameter annotation checking
  205. expected = new HashSet<String>();
  206. expected.addAll(mpnv.getParameterAnnotations());
  207. st = new StringTokenizer(expectedParameterAnnotations==null?"":expectedParameterAnnotations);
  208. while (st.hasMoreTokens()) {
  209. String nextToken = st.nextToken();
  210. if (!expected.contains(nextToken))
  211. fail("In pointcut expression "+pe.getPointcutExpression()+" parameter "+parameterNumber+". The annotation type pattern did not include parameter annotation "+nextToken+". It's full set was "+mpnv.getParameterAnnotations());
  212. expected.remove(nextToken);
  213. }
  214. if (expected.size()>0) { // we have excess ones!
  215. StringBuffer excessTokens = new StringBuffer();
  216. for (Iterator iterator = expected.iterator(); iterator.hasNext();) {
  217. String string = (String) iterator.next();
  218. excessTokens.append(string).append(" ");
  219. }
  220. fail("In pointcut expression "+pe.getPointcutExpression()+" parameter "+parameterNumber+". The annotation type pattern has these unexpected parameter annotations "+excessTokens.toString());
  221. }
  222. }
  223. static class MyPatternNodeVisitor extends AbstractPatternNodeVisitor {
  224. private StringBuffer stringRep = new StringBuffer();
  225. private List<String> parameterAnnotations = new ArrayList<String>();
  226. private List<String> parameterTypeAnnotations = new ArrayList<String>();
  227. public String getStringRepresentation() { return stringRep.toString(); }
  228. public List<String> getParameterAnnotations() { return parameterAnnotations; }
  229. public List<String> getParameterTypeAnnotations() { return parameterTypeAnnotations; }
  230. public Object visit(AndAnnotationTypePattern node, Object data) {
  231. stringRep.append("(");
  232. node.getLeft().accept(this, data);
  233. stringRep.append(" and ");
  234. node.getRight().accept(this, data);
  235. stringRep.append(")");
  236. return node;
  237. }
  238. public Object visit(AnyAnnotationTypePattern node, Object data) {
  239. stringRep.append("any");
  240. return node;
  241. }
  242. public Object visit(ExactAnnotationTypePattern node, Object data) {
  243. stringRep.append("exact["+stringify(node.getResolvedAnnotationType())+":"+(node.isForParameterAnnotationMatch()?"p":"t")+"]");
  244. if (node.isForParameterAnnotationMatch()) {
  245. parameterAnnotations.add(stringify(node.getResolvedAnnotationType()));
  246. } else {
  247. parameterTypeAnnotations.add(stringify(node.getResolvedAnnotationType()));
  248. }
  249. return node;
  250. }
  251. private String stringify(ResolvedType resolvedAnnotationType) {
  252. return "@"+resolvedAnnotationType.getSimpleName();
  253. }
  254. public Object visit(BindingAnnotationTypePattern node, Object data) {
  255. stringRep.append("binding");
  256. return node;
  257. }
  258. public Object visit(NotAnnotationTypePattern node, Object data) {
  259. stringRep.append("not");
  260. return node;
  261. }
  262. public Object visit(OrAnnotationTypePattern node, Object data) {
  263. stringRep.append("(");
  264. node.getLeft().accept(this, data);
  265. stringRep.append(" or ");
  266. node.getRight().accept(this, data);
  267. stringRep.append(")");
  268. return node;
  269. }
  270. public Object visit(WildAnnotationTypePattern node, Object data) {
  271. stringRep.append("wild[");
  272. stringRep.append(node.getTypePattern().toString());
  273. stringRep.append("]");
  274. return node;
  275. }
  276. public Object visit(AnnotationPatternList node, Object data) {
  277. stringRep.append("list");
  278. return node;
  279. }
  280. }
  281. public void testAtThis() {
  282. PointcutExpression atThis = parser.parsePointcutExpression("@this(org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)");
  283. ShadowMatch sMatch1 = atThis.matchesMethodExecution(a);
  284. ShadowMatch sMatch2 = atThis.matchesMethodExecution(b);
  285. assertTrue("maybe matches A",sMatch1.maybeMatches());
  286. assertTrue("maybe matches B",sMatch2.maybeMatches());
  287. JoinPointMatch jp1 = sMatch1.matchesJoinPoint(new A(), new A(), new Object[0]);
  288. assertFalse("does not match",jp1.matches());
  289. JoinPointMatch jp2 = sMatch2.matchesJoinPoint(new B(), new B(), new Object[0]);
  290. assertTrue("matches",jp2.matches());
  291. }
  292. public void testAtTarget() {
  293. PointcutExpression atTarget = parser.parsePointcutExpression("@target(org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)");
  294. ShadowMatch sMatch1 = atTarget.matchesMethodExecution(a);
  295. ShadowMatch sMatch2 = atTarget.matchesMethodExecution(b);
  296. assertTrue("maybe matches A",sMatch1.maybeMatches());
  297. assertTrue("maybe matches B",sMatch2.maybeMatches());
  298. JoinPointMatch jp1 = sMatch1.matchesJoinPoint(new A(), new A(), new Object[0]);
  299. assertFalse("does not match",jp1.matches());
  300. JoinPointMatch jp2 = sMatch2.matchesJoinPoint(new B(), new B(), new Object[0]);
  301. assertTrue("matches",jp2.matches());
  302. }
  303. public void testAtThisWithBinding() {
  304. PointcutParameter param = parser.createPointcutParameter("a",MyAnnotation.class);
  305. B myB = new B();
  306. MyAnnotation bAnnotation = B.class.getAnnotation(MyAnnotation.class);
  307. PointcutExpression atThis = parser.parsePointcutExpression("@this(a)",A.class,new PointcutParameter[] {param});
  308. ShadowMatch sMatch1 = atThis.matchesMethodExecution(a);
  309. ShadowMatch sMatch2 = atThis.matchesMethodExecution(b);
  310. assertTrue("maybe matches A",sMatch1.maybeMatches());
  311. assertTrue("maybe matches B",sMatch2.maybeMatches());
  312. JoinPointMatch jp1 = sMatch1.matchesJoinPoint(new A(), new A(), new Object[0]);
  313. assertFalse("does not match",jp1.matches());
  314. JoinPointMatch jp2 = sMatch2.matchesJoinPoint(myB, myB, new Object[0]);
  315. assertTrue("matches",jp2.matches());
  316. assertEquals(1,jp2.getParameterBindings().length);
  317. assertEquals("should be myB's annotation",bAnnotation,jp2.getParameterBindings()[0].getBinding());
  318. }
  319. public void testAtTargetWithBinding() {
  320. PointcutParameter param = parser.createPointcutParameter("a",MyAnnotation.class);
  321. B myB = new B();
  322. MyAnnotation bAnnotation = B.class.getAnnotation(MyAnnotation.class);
  323. PointcutExpression atThis = parser.parsePointcutExpression("@target(a)",A.class,new PointcutParameter[] {param});
  324. ShadowMatch sMatch1 = atThis.matchesMethodExecution(a);
  325. ShadowMatch sMatch2 = atThis.matchesMethodExecution(b);
  326. assertTrue("maybe matches A",sMatch1.maybeMatches());
  327. assertTrue("maybe matches B",sMatch2.maybeMatches());
  328. JoinPointMatch jp1 = sMatch1.matchesJoinPoint(new A(), new A(), new Object[0]);
  329. assertFalse("does not match",jp1.matches());
  330. JoinPointMatch jp2 = sMatch2.matchesJoinPoint(myB, myB, new Object[0]);
  331. assertTrue("matches",jp2.matches());
  332. assertEquals(1,jp2.getParameterBindings().length);
  333. assertEquals("should be myB's annotation",bAnnotation,jp2.getParameterBindings()[0].getBinding());
  334. }
  335. public void testAtArgs() {
  336. PointcutExpression atArgs = parser.parsePointcutExpression("@args(..,org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)");
  337. ShadowMatch sMatch1 = atArgs.matchesMethodExecution(a);
  338. ShadowMatch sMatch2 = atArgs.matchesMethodExecution(c);
  339. assertTrue("never matches A",sMatch1.neverMatches());
  340. assertTrue("maybe matches C",sMatch2.maybeMatches());
  341. JoinPointMatch jp2 = sMatch2.matchesJoinPoint(new B(), new B(), new Object[]{new A(),new B()});
  342. assertTrue("matches",jp2.matches());
  343. atArgs = parser.parsePointcutExpression("@args(org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation,org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)");
  344. sMatch1 = atArgs.matchesMethodExecution(a);
  345. sMatch2 = atArgs.matchesMethodExecution(c);
  346. assertTrue("never matches A",sMatch1.neverMatches());
  347. assertTrue("maybe matches C",sMatch2.maybeMatches());
  348. JoinPointMatch jp1 = sMatch2.matchesJoinPoint(new A(), new A(), new Object[] {new A(), new B()});
  349. assertFalse("does not match",jp1.matches());
  350. jp2 = sMatch2.matchesJoinPoint(new B(), new B(), new Object[] {new B(),new B()});
  351. assertTrue("matches",jp2.matches());
  352. }
  353. public void testAtArgs2() {
  354. PointcutExpression atArgs = parser.parsePointcutExpression("@args(*, org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)");
  355. ShadowMatch sMatch1 = atArgs.matchesMethodExecution(c);
  356. ShadowMatch sMatch2 = atArgs.matchesMethodExecution(d);
  357. assertTrue("maybe matches c",sMatch1.maybeMatches());
  358. assertTrue("maybe matches d",sMatch2.maybeMatches());
  359. JoinPointMatch jp1 = sMatch1.matchesJoinPoint(new B(), new B(), new Object[] {new A(), new B()});
  360. assertTrue("matches",jp1.matches());
  361. JoinPointMatch jp2 = sMatch2.matchesJoinPoint(new B(), new B(), new Object[] {new A(),new A()});
  362. assertFalse("does not match",jp2.matches());
  363. }
  364. public void testAtArgsWithBinding() {
  365. PointcutParameter p1 = parser.createPointcutParameter("a",MyAnnotation.class);
  366. PointcutParameter p2 = parser.createPointcutParameter("b", MyAnnotation.class);
  367. PointcutExpression atArgs = parser.parsePointcutExpression("@args(..,a)",A.class,new PointcutParameter[] {p1});
  368. ShadowMatch sMatch2 = atArgs.matchesMethodExecution(c);
  369. assertTrue("maybe matches C",sMatch2.maybeMatches());
  370. JoinPointMatch jp2 = sMatch2.matchesJoinPoint(new B(), new B(), new Object[]{new A(),new B()});
  371. assertTrue("matches",jp2.matches());
  372. assertEquals(1,jp2.getParameterBindings().length);
  373. MyAnnotation bAnnotation = B.class.getAnnotation(MyAnnotation.class);
  374. assertEquals("annotation on B",bAnnotation,jp2.getParameterBindings()[0].getBinding());
  375. atArgs = parser.parsePointcutExpression("@args(a,b)",A.class,new PointcutParameter[] {p1,p2});
  376. sMatch2 = atArgs.matchesMethodExecution(c);
  377. assertTrue("maybe matches C",sMatch2.maybeMatches());
  378. jp2 = sMatch2.matchesJoinPoint(new B(), new B(), new Object[] {new B(),new B()});
  379. assertTrue("matches",jp2.matches());
  380. assertEquals(2,jp2.getParameterBindings().length);
  381. assertEquals("annotation on B",bAnnotation,jp2.getParameterBindings()[0].getBinding());
  382. assertEquals("annotation on B",bAnnotation,jp2.getParameterBindings()[1].getBinding());
  383. }
  384. public void testAtWithin() {
  385. PointcutExpression atWithin = parser.parsePointcutExpression("@within(org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)");
  386. ShadowMatch sMatch1 = atWithin.matchesMethodExecution(a);
  387. ShadowMatch sMatch2 = atWithin.matchesMethodExecution(b);
  388. assertTrue("does not match a",sMatch1.neverMatches());
  389. assertTrue("matches b",sMatch2.alwaysMatches());
  390. }
  391. public void testAtWithinWithBinding() {
  392. PointcutParameter p1 = parser.createPointcutParameter("x",MyAnnotation.class);
  393. PointcutExpression atWithin = parser.parsePointcutExpression("@within(x)",B.class,new PointcutParameter[] {p1});
  394. ShadowMatch sMatch1 = atWithin.matchesMethodExecution(a);
  395. ShadowMatch sMatch2 = atWithin.matchesMethodExecution(b);
  396. assertTrue("does not match a",sMatch1.neverMatches());
  397. assertTrue("matches b",sMatch2.alwaysMatches());
  398. JoinPointMatch jpm = sMatch2.matchesJoinPoint(new B(), new B(), new Object[0]);
  399. assertTrue(jpm.matches());
  400. assertEquals(1,jpm.getParameterBindings().length);
  401. MyAnnotation bAnnotation = B.class.getAnnotation(MyAnnotation.class);
  402. assertEquals("annotation on B",bAnnotation,jpm.getParameterBindings()[0].getBinding());
  403. }
  404. public void testAtWithinCode() {
  405. PointcutExpression atWithinCode = parser.parsePointcutExpression("@withincode(org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)");
  406. ShadowMatch sMatch1 = atWithinCode.matchesMethodCall(a,b);
  407. ShadowMatch sMatch2 = atWithinCode.matchesMethodCall(a,a);
  408. assertTrue("does not match from b",sMatch1.neverMatches());
  409. assertTrue("matches from a",sMatch2.alwaysMatches());
  410. }
  411. public void testAtWithinCodeWithBinding() {
  412. PointcutParameter p1 = parser.createPointcutParameter("x",MyAnnotation.class);
  413. PointcutExpression atWithinCode = parser.parsePointcutExpression("@withincode(x)",A.class,new PointcutParameter[] {p1});
  414. ShadowMatch sMatch2 = atWithinCode.matchesMethodCall(a,a);
  415. assertTrue("matches from a",sMatch2.alwaysMatches());
  416. JoinPointMatch jpm = sMatch2.matchesJoinPoint(new A(), new A(), new Object[0]);
  417. assertEquals(1,jpm.getParameterBindings().length);
  418. MyAnnotation annOna = a.getAnnotation(MyAnnotation.class);
  419. assertEquals("MyAnnotation on a",annOna,jpm.getParameterBindings()[0].getBinding());
  420. }
  421. public void testAtAnnotation() {
  422. PointcutExpression atAnnotation = parser.parsePointcutExpression("@annotation(org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)");
  423. ShadowMatch sMatch1 = atAnnotation.matchesMethodCall(b,a);
  424. ShadowMatch sMatch2 = atAnnotation.matchesMethodCall(a,a);
  425. assertTrue("does not match call to b",sMatch1.neverMatches());
  426. assertTrue("matches call to a",sMatch2.alwaysMatches());
  427. }
  428. public void testAtAnnotationWithBinding() {
  429. PointcutParameter p1 = parser.createPointcutParameter("x",MyAnnotation.class);
  430. PointcutExpression atAnnotation = parser.parsePointcutExpression("@annotation(x)",A.class,new PointcutParameter[] {p1});
  431. ShadowMatch sMatch2 = atAnnotation.matchesMethodCall(a,a);
  432. assertTrue("matches call to a",sMatch2.alwaysMatches());
  433. JoinPointMatch jpm = sMatch2.matchesJoinPoint(new A(), new A(), new Object[0]);
  434. assertTrue(jpm.matches());
  435. assertEquals(1,jpm.getParameterBindings().length);
  436. MyAnnotation annOna = a.getAnnotation(MyAnnotation.class);
  437. assertEquals("MyAnnotation on a",annOna,jpm.getParameterBindings()[0].getBinding());
  438. }
  439. public void testReferencePointcutNoParams() {
  440. PointcutExpression pc = parser.parsePointcutExpression("foo()",C.class,new PointcutParameter[0]);
  441. ShadowMatch sMatch1 = pc.matchesMethodCall(a,b);
  442. ShadowMatch sMatch2 = pc.matchesMethodExecution(a);
  443. assertTrue("no match on call",sMatch1.neverMatches());
  444. assertTrue("match on execution",sMatch2.alwaysMatches());
  445. pc = parser.parsePointcutExpression("org.aspectj.weaver.tools.Java15PointcutExpressionTest.C.foo()");
  446. sMatch1 = pc.matchesMethodCall(a,b);
  447. sMatch2 = pc.matchesMethodExecution(a);
  448. assertTrue("no match on call",sMatch1.neverMatches());
  449. assertTrue("match on execution",sMatch2.alwaysMatches());
  450. }
  451. public void testReferencePointcutParams() {
  452. PointcutParameter p1 = parser.createPointcutParameter("x",A.class);
  453. PointcutExpression pc = parser.parsePointcutExpression("goo(x)",C.class,new PointcutParameter[] {p1});
  454. ShadowMatch sMatch1 = pc.matchesMethodCall(a,b);
  455. ShadowMatch sMatch2 = pc.matchesMethodExecution(a);
  456. assertTrue("no match on call",sMatch1.neverMatches());
  457. assertTrue("match on execution",sMatch2.maybeMatches());
  458. A anA = new A();
  459. JoinPointMatch jpm = sMatch2.matchesJoinPoint(anA, new A(), new Object[0]);
  460. assertTrue(jpm.matches());
  461. assertEquals("should be bound to anA",anA,jpm.getParameterBindings()[0].getBinding());
  462. }
  463. public void testExecutionWithClassFileRetentionAnnotation() {
  464. PointcutExpression pc1 = parser.parsePointcutExpression("execution(@org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation * *(..))");
  465. PointcutExpression pc2 = parser.parsePointcutExpression("execution(@org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyClassFileRetentionAnnotation * *(..))");
  466. ShadowMatch sMatch = pc1.matchesMethodExecution(a);
  467. assertTrue("matches",sMatch.alwaysMatches());
  468. sMatch = pc2.matchesMethodExecution(a);
  469. assertTrue("no match",sMatch.neverMatches());
  470. sMatch = pc1.matchesMethodExecution(b);
  471. assertTrue("no match",sMatch.neverMatches());
  472. sMatch = pc2.matchesMethodExecution(b);
  473. assertTrue("matches",sMatch.alwaysMatches());
  474. }
  475. public void testGenericMethodSignatures() throws Exception{
  476. PointcutExpression ex = parser.parsePointcutExpression("execution(* set*(java.util.List<org.aspectj.weaver.tools.Java15PointcutExpressionTest.C>))");
  477. Method m = TestBean.class.getMethod("setFriends",List.class);
  478. ShadowMatch sm = ex.matchesMethodExecution(m);
  479. assertTrue("should match",sm.alwaysMatches());
  480. }
  481. public void testAnnotationInExecution() throws Exception {
  482. PointcutExpression ex = parser.parsePointcutExpression("execution(@(org.springframework..*) * *(..))");
  483. }
  484. public void testVarArgsMatching() throws Exception {
  485. PointcutExpression ex = parser.parsePointcutExpression("execution(* *(String...))");
  486. Method usesVarArgs = D.class.getMethod("varArgs",String[].class);
  487. Method noVarArgs = D.class.getMethod("nonVarArgs", String[].class);
  488. ShadowMatch sm1 = ex.matchesMethodExecution(usesVarArgs);
  489. assertTrue("should match",sm1.alwaysMatches());
  490. ShadowMatch sm2 = ex.matchesMethodExecution(noVarArgs);
  491. assertFalse("should not match",sm2.alwaysMatches());
  492. }
  493. public void testJavaLangMatching() throws Exception {
  494. PointcutExpression ex = parser.parsePointcutExpression("@within(java.lang.Deprecated)");
  495. Method foo = GoldenOldie.class.getMethod("foo");
  496. ShadowMatch sm1 = ex.matchesMethodExecution(foo);
  497. assertTrue("should match",sm1.alwaysMatches());
  498. }
  499. public void testReferencePCsInSameType() throws Exception {
  500. PointcutExpression ex = parser.parsePointcutExpression("org.aspectj.weaver.tools.Java15PointcutExpressionTest.NamedPointcutResolution.c()",NamedPointcutResolution.class,new PointcutParameter[0]);
  501. ShadowMatch sm = ex.matchesMethodExecution(a);
  502. assertTrue("should match",sm.alwaysMatches());
  503. sm = ex.matchesMethodExecution(b);
  504. assertTrue("does not match",sm.neverMatches());
  505. }
  506. public void testReferencePCsInOtherType() throws Exception {
  507. PointcutExpression ex = parser.parsePointcutExpression("org.aspectj.weaver.tools.Java15PointcutExpressionTest.ExternalReferrer.d()",ExternalReferrer.class,new PointcutParameter[0]);
  508. ShadowMatch sm = ex.matchesMethodExecution(a);
  509. assertTrue("should match",sm.alwaysMatches());
  510. sm = ex.matchesMethodExecution(b);
  511. assertTrue("does not match",sm.neverMatches());
  512. }
  513. public void testArrayTypeInArgs() throws Exception {
  514. PointcutParameter[] params = new PointcutParameter[3];
  515. params[0] = parser.createPointcutParameter("d", Date.class);
  516. params[1] = parser.createPointcutParameter("s", String.class);
  517. params[2] = parser.createPointcutParameter("ss", String[].class);
  518. PointcutExpression ex = parser.parsePointcutExpression("org.aspectj.weaver.tools.Java15PointcutExpressionTest.UsesArrays.pc(d,s,ss)",UsesArrays.class,params);
  519. }
  520. protected void setUp() throws Exception {
  521. super.setUp();
  522. parser = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingSpecifiedClassloaderForResolution(this.getClass().getClassLoader());
  523. a = A.class.getMethod("a");
  524. b = B.class.getMethod("b");
  525. c = B.class.getMethod("c",new Class[] {A.class,B.class});
  526. d = B.class.getMethod("d",new Class[] {A.class,A.class});
  527. }
  528. @Retention(RetentionPolicy.RUNTIME)
  529. private @interface MyAnnotation {}
  530. private @interface MyClassFileRetentionAnnotation {}
  531. private static class A {
  532. @MyAnnotation public void a() {}
  533. }
  534. @MyAnnotation
  535. private static class B {
  536. @MyClassFileRetentionAnnotation public void b() {}
  537. public void c(A anA, B aB) {}
  538. public void d(A anA, A anotherA) {}
  539. }
  540. private static class C {
  541. @Pointcut("execution(* *(..))")
  542. public void foo() {}
  543. @Pointcut(value="execution(* *(..)) && this(x)", argNames="x")
  544. public void goo(A x) {}
  545. }
  546. private static class D {
  547. public void nonVarArgs(String[] strings) {};
  548. public void varArgs(String... strings) {};
  549. }
  550. static class TestBean {
  551. public void setFriends(List<C> friends) {}
  552. }
  553. @Deprecated
  554. static class GoldenOldie {
  555. public void foo() {}
  556. }
  557. private static class NamedPointcutResolution {
  558. @Pointcut("execution(* *(..))")
  559. public void a() {}
  560. @Pointcut("this(org.aspectj.weaver.tools.Java15PointcutExpressionTest.A)")
  561. public void b() {}
  562. @Pointcut("a() && b()")
  563. public void c() {}
  564. }
  565. private static class ExternalReferrer {
  566. @Pointcut("org.aspectj.weaver.tools.Java15PointcutExpressionTest.NamedPointcutResolution.a() && " +
  567. "org.aspectj.weaver.tools.Java15PointcutExpressionTest.NamedPointcutResolution.b())")
  568. public void d() {}
  569. }
  570. private static class UsesArrays {
  571. @Pointcut("execution(* *(..)) && args(d,s,ss)")
  572. public void pc(Date d, String s, String[] ss) {}
  573. }
  574. }