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.

PointcutExpressionImpl.java 15KB

15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  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 v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/epl-v10.html
  8. *
  9. * ******************************************************************/
  10. package org.aspectj.weaver.internal.tools;
  11. import java.lang.reflect.Constructor;
  12. import java.lang.reflect.Field;
  13. import java.lang.reflect.Member;
  14. import java.lang.reflect.Method;
  15. import org.aspectj.weaver.ResolvedType;
  16. import org.aspectj.weaver.Shadow;
  17. import org.aspectj.weaver.World;
  18. import org.aspectj.weaver.ast.Literal;
  19. import org.aspectj.weaver.ast.Test;
  20. import org.aspectj.weaver.patterns.AbstractPatternNodeVisitor;
  21. import org.aspectj.weaver.patterns.AnnotationPointcut;
  22. import org.aspectj.weaver.patterns.ArgsAnnotationPointcut;
  23. import org.aspectj.weaver.patterns.ArgsPointcut;
  24. import org.aspectj.weaver.patterns.CflowPointcut;
  25. import org.aspectj.weaver.patterns.ExposedState;
  26. import org.aspectj.weaver.patterns.IfPointcut;
  27. import org.aspectj.weaver.patterns.NotAnnotationTypePattern;
  28. import org.aspectj.weaver.patterns.NotPointcut;
  29. import org.aspectj.weaver.patterns.Pointcut;
  30. import org.aspectj.weaver.patterns.ThisOrTargetAnnotationPointcut;
  31. import org.aspectj.weaver.patterns.ThisOrTargetPointcut;
  32. import org.aspectj.weaver.patterns.WithinAnnotationPointcut;
  33. import org.aspectj.weaver.patterns.WithinCodeAnnotationPointcut;
  34. import org.aspectj.weaver.reflect.ReflectionFastMatchInfo;
  35. import org.aspectj.weaver.reflect.ReflectionShadow;
  36. import org.aspectj.weaver.reflect.ReflectionWorld;
  37. import org.aspectj.weaver.reflect.ShadowMatchImpl;
  38. import org.aspectj.weaver.tools.DefaultMatchingContext;
  39. import org.aspectj.weaver.tools.MatchingContext;
  40. import org.aspectj.weaver.tools.PointcutExpression;
  41. import org.aspectj.weaver.tools.PointcutParameter;
  42. import org.aspectj.weaver.tools.ShadowMatch;
  43. /**
  44. * Map from weaver.tools interface to internal Pointcut implementation...
  45. */
  46. public class PointcutExpressionImpl implements PointcutExpression {
  47. private final static boolean MATCH_INFO = false;
  48. private World world;
  49. private Pointcut pointcut;
  50. private String expression;
  51. private PointcutParameter[] parameters;
  52. private MatchingContext matchContext = new DefaultMatchingContext();
  53. public PointcutExpressionImpl(Pointcut pointcut, String expression, PointcutParameter[] params, World inWorld) {
  54. this.pointcut = pointcut;
  55. this.expression = expression;
  56. this.world = inWorld;
  57. this.parameters = params;
  58. if (this.parameters == null) {
  59. this.parameters = new PointcutParameter[0];
  60. }
  61. }
  62. public Pointcut getUnderlyingPointcut() {
  63. return this.pointcut;
  64. }
  65. /*
  66. * (non-Javadoc)
  67. *
  68. * @see org.aspectj.weaver.tools.PointcutExpression#setMatchingContext(org.aspectj.weaver.tools.MatchingContext)
  69. */
  70. public void setMatchingContext(MatchingContext aMatchContext) {
  71. this.matchContext = aMatchContext;
  72. }
  73. public boolean couldMatchJoinPointsInType(Class aClass) {
  74. ResolvedType matchType = world.resolve(aClass.getName());
  75. if (matchType.isMissing() && (world instanceof ReflectionWorld)) {
  76. // Class is a generated class that cannot be 'looked up' via getResource.
  77. // For example a proxy or lambda.
  78. // Use the class itself in this case
  79. matchType = ((ReflectionWorld)world).resolveUsingClass(aClass);
  80. }
  81. ReflectionFastMatchInfo info = new ReflectionFastMatchInfo(matchType, null, this.matchContext, world);
  82. boolean couldMatch = pointcut.fastMatch(info).maybeTrue();
  83. if (MATCH_INFO) {
  84. System.out.println("MATCHINFO: fast match for '" + this.expression + "' against '" + aClass.getName() + "': "
  85. + couldMatch);
  86. }
  87. return couldMatch;
  88. }
  89. public boolean mayNeedDynamicTest() {
  90. HasPossibleDynamicContentVisitor visitor = new HasPossibleDynamicContentVisitor();
  91. pointcut.traverse(visitor, null);
  92. return visitor.hasDynamicContent();
  93. }
  94. private ExposedState getExposedState() {
  95. return new ExposedState(parameters.length);
  96. }
  97. public ShadowMatch matchesMethodExecution(Method aMethod) {
  98. ShadowMatch match = matchesExecution(aMethod);
  99. if (MATCH_INFO && match.maybeMatches()) {
  100. System.out.println("MATCHINFO: method execution match on '" + aMethod + "' for '" + this.expression + "': "
  101. + (match.alwaysMatches() ? "YES" : "MAYBE"));
  102. }
  103. return match;
  104. }
  105. public ShadowMatch matchesConstructorExecution(Constructor aConstructor) {
  106. ShadowMatch match = matchesExecution(aConstructor);
  107. if (MATCH_INFO && match.maybeMatches()) {
  108. System.out.println("MATCHINFO: constructor execution match on '" + aConstructor + "' for '" + this.expression + "': "
  109. + (match.alwaysMatches() ? "YES" : "MAYBE"));
  110. }
  111. return match;
  112. }
  113. private ShadowMatch matchesExecution(Member aMember) {
  114. Shadow s = ReflectionShadow.makeExecutionShadow(world, aMember, this.matchContext);
  115. ShadowMatchImpl sm = getShadowMatch(s);
  116. sm.setSubject(aMember);
  117. sm.setWithinCode(null);
  118. sm.setWithinType(aMember.getDeclaringClass());
  119. return sm;
  120. }
  121. public ShadowMatch matchesStaticInitialization(Class aClass) {
  122. Shadow s = ReflectionShadow.makeStaticInitializationShadow(world, aClass, this.matchContext);
  123. ShadowMatchImpl sm = getShadowMatch(s);
  124. sm.setSubject(null);
  125. sm.setWithinCode(null);
  126. sm.setWithinType(aClass);
  127. if (MATCH_INFO && sm.maybeMatches()) {
  128. System.out.println("MATCHINFO: static initialization match on '" + aClass.getName() + "' for '" + this.expression
  129. + "': " + (sm.alwaysMatches() ? "YES" : "MAYBE"));
  130. }
  131. return sm;
  132. }
  133. public ShadowMatch matchesAdviceExecution(Method aMethod) {
  134. Shadow s = ReflectionShadow.makeAdviceExecutionShadow(world, aMethod, this.matchContext);
  135. ShadowMatchImpl sm = getShadowMatch(s);
  136. sm.setSubject(aMethod);
  137. sm.setWithinCode(null);
  138. sm.setWithinType(aMethod.getDeclaringClass());
  139. if (MATCH_INFO && sm.maybeMatches()) {
  140. System.out.println("MATCHINFO: advice execution match on '" + aMethod + "' for '" + this.expression + "': "
  141. + (sm.alwaysMatches() ? "YES" : "MAYBE"));
  142. }
  143. return sm;
  144. }
  145. public ShadowMatch matchesInitialization(Constructor aConstructor) {
  146. Shadow s = ReflectionShadow.makeInitializationShadow(world, aConstructor, this.matchContext);
  147. ShadowMatchImpl sm = getShadowMatch(s);
  148. sm.setSubject(aConstructor);
  149. sm.setWithinCode(null);
  150. sm.setWithinType(aConstructor.getDeclaringClass());
  151. if (MATCH_INFO && sm.maybeMatches()) {
  152. System.out.println("MATCHINFO: initialization match on '" + aConstructor + "' for '" + this.expression + "': "
  153. + (sm.alwaysMatches() ? "YES" : "MAYBE"));
  154. }
  155. return sm;
  156. }
  157. public ShadowMatch matchesPreInitialization(Constructor aConstructor) {
  158. Shadow s = ReflectionShadow.makePreInitializationShadow(world, aConstructor, this.matchContext);
  159. ShadowMatchImpl sm = getShadowMatch(s);
  160. sm.setSubject(aConstructor);
  161. sm.setWithinCode(null);
  162. sm.setWithinType(aConstructor.getDeclaringClass());
  163. if (MATCH_INFO && sm.maybeMatches()) {
  164. System.out.println("MATCHINFO: preinitialization match on '" + aConstructor + "' for '" + this.expression + "': "
  165. + (sm.alwaysMatches() ? "YES" : "MAYBE"));
  166. }
  167. return sm;
  168. }
  169. public ShadowMatch matchesMethodCall(Method aMethod, Member withinCode) {
  170. Shadow s = ReflectionShadow.makeCallShadow(world, aMethod, withinCode, this.matchContext);
  171. ShadowMatchImpl sm = getShadowMatch(s);
  172. sm.setSubject(aMethod);
  173. sm.setWithinCode(withinCode);
  174. sm.setWithinType(withinCode.getDeclaringClass());
  175. if (MATCH_INFO && sm.maybeMatches()) {
  176. System.out.println("MATCHINFO: method call match on '" + aMethod + "' withinCode='" + withinCode + "' for '"
  177. + this.expression + "': " + (sm.alwaysMatches() ? "YES" : "MAYBE"));
  178. }
  179. return sm;
  180. }
  181. public ShadowMatch matchesMethodCall(Method aMethod, Class callerType) {
  182. Shadow s = ReflectionShadow.makeCallShadow(world, aMethod, callerType, this.matchContext);
  183. ShadowMatchImpl sm = getShadowMatch(s);
  184. sm.setSubject(aMethod);
  185. sm.setWithinCode(null);
  186. sm.setWithinType(callerType);
  187. if (MATCH_INFO && sm.maybeMatches()) {
  188. System.out.println("MATCHINFO: method call match on '" + aMethod + "' callerType='" + callerType.getName() + "' for '"
  189. + this.expression + "': " + (sm.alwaysMatches() ? "YES" : "MAYBE"));
  190. }
  191. return sm;
  192. }
  193. public ShadowMatch matchesConstructorCall(Constructor aConstructor, Class callerType) {
  194. Shadow s = ReflectionShadow.makeCallShadow(world, aConstructor, callerType, this.matchContext);
  195. ShadowMatchImpl sm = getShadowMatch(s);
  196. sm.setSubject(aConstructor);
  197. sm.setWithinCode(null);
  198. sm.setWithinType(callerType);
  199. if (MATCH_INFO && sm.maybeMatches()) {
  200. System.out.println("MATCHINFO: constructor call match on '" + aConstructor + "' callerType='" + callerType.getName()
  201. + "' for '" + this.expression + "': " + (sm.alwaysMatches() ? "YES" : "MAYBE"));
  202. }
  203. return sm;
  204. }
  205. public ShadowMatch matchesConstructorCall(Constructor aConstructor, Member withinCode) {
  206. Shadow s = ReflectionShadow.makeCallShadow(world, aConstructor, withinCode, this.matchContext);
  207. ShadowMatchImpl sm = getShadowMatch(s);
  208. sm.setSubject(aConstructor);
  209. sm.setWithinCode(withinCode);
  210. sm.setWithinType(withinCode.getDeclaringClass());
  211. if (MATCH_INFO && sm.maybeMatches()) {
  212. System.out.println("MATCHINFO: constructor call match on '" + aConstructor + "' withinCode='" + withinCode + "' for '"
  213. + this.expression + "': " + (sm.alwaysMatches() ? "YES" : "MAYBE"));
  214. }
  215. return sm;
  216. }
  217. public ShadowMatch matchesHandler(Class exceptionType, Class handlingType) {
  218. Shadow s = ReflectionShadow.makeHandlerShadow(world, exceptionType, handlingType, this.matchContext);
  219. ShadowMatchImpl sm = getShadowMatch(s);
  220. sm.setSubject(null);
  221. sm.setWithinCode(null);
  222. sm.setWithinType(handlingType);
  223. if (MATCH_INFO && sm.maybeMatches()) {
  224. System.out.println("MATCHINFO: handler match on '" + exceptionType.getName() + "' handlingType='" + handlingType
  225. + "' for '" + this.expression + "': " + (sm.alwaysMatches() ? "YES" : "MAYBE"));
  226. }
  227. return sm;
  228. }
  229. public ShadowMatch matchesHandler(Class exceptionType, Member withinCode) {
  230. Shadow s = ReflectionShadow.makeHandlerShadow(world, exceptionType, withinCode, this.matchContext);
  231. ShadowMatchImpl sm = getShadowMatch(s);
  232. sm.setSubject(null);
  233. sm.setWithinCode(withinCode);
  234. sm.setWithinType(withinCode.getDeclaringClass());
  235. if (MATCH_INFO && sm.maybeMatches()) {
  236. System.out.println("MATCHINFO: handler match on '" + exceptionType.getName() + "' withinCode='" + withinCode
  237. + "' for '" + this.expression + "': " + (sm.alwaysMatches() ? "YES" : "MAYBE"));
  238. }
  239. return sm;
  240. }
  241. public ShadowMatch matchesFieldGet(Field aField, Class withinType) {
  242. Shadow s = ReflectionShadow.makeFieldGetShadow(world, aField, withinType, this.matchContext);
  243. ShadowMatchImpl sm = getShadowMatch(s);
  244. sm.setSubject(aField);
  245. sm.setWithinCode(null);
  246. sm.setWithinType(withinType);
  247. if (MATCH_INFO && sm.maybeMatches()) {
  248. System.out.println("MATCHINFO: field get match on '" + aField + "' withinType='" + withinType.getName() + "' for '"
  249. + this.expression + "': " + (sm.alwaysMatches() ? "YES" : "MAYBE"));
  250. }
  251. return sm;
  252. }
  253. public ShadowMatch matchesFieldGet(Field aField, Member withinCode) {
  254. Shadow s = ReflectionShadow.makeFieldGetShadow(world, aField, withinCode, this.matchContext);
  255. ShadowMatchImpl sm = getShadowMatch(s);
  256. sm.setSubject(aField);
  257. sm.setWithinCode(withinCode);
  258. sm.setWithinType(withinCode.getDeclaringClass());
  259. if (MATCH_INFO && sm.maybeMatches()) {
  260. System.out.println("MATCHINFO: field get match on '" + aField + "' withinCode='" + withinCode + "' for '"
  261. + this.expression + "': " + (sm.alwaysMatches() ? "YES" : "MAYBE"));
  262. }
  263. return sm;
  264. }
  265. public ShadowMatch matchesFieldSet(Field aField, Class withinType) {
  266. Shadow s = ReflectionShadow.makeFieldSetShadow(world, aField, withinType, this.matchContext);
  267. ShadowMatchImpl sm = getShadowMatch(s);
  268. sm.setSubject(aField);
  269. sm.setWithinCode(null);
  270. sm.setWithinType(withinType);
  271. if (MATCH_INFO && sm.maybeMatches()) {
  272. System.out.println("MATCHINFO: field set match on '" + aField + "' withinType='" + withinType.getName() + "' for '"
  273. + this.expression + "': " + (sm.alwaysMatches() ? "YES" : "MAYBE"));
  274. }
  275. return sm;
  276. }
  277. public ShadowMatch matchesFieldSet(Field aField, Member withinCode) {
  278. Shadow s = ReflectionShadow.makeFieldSetShadow(world, aField, withinCode, this.matchContext);
  279. ShadowMatchImpl sm = getShadowMatch(s);
  280. sm.setSubject(aField);
  281. sm.setWithinCode(withinCode);
  282. sm.setWithinType(withinCode.getDeclaringClass());
  283. if (MATCH_INFO && sm.maybeMatches()) {
  284. System.out.println("MATCHINFO: field set match on '" + aField + "' withinCode='" + withinCode + "' for '"
  285. + this.expression + "': " + (sm.alwaysMatches() ? "YES" : "MAYBE"));
  286. }
  287. return sm;
  288. }
  289. private ShadowMatchImpl getShadowMatch(Shadow forShadow) {
  290. org.aspectj.util.FuzzyBoolean match = pointcut.match(forShadow);
  291. Test residueTest = Literal.TRUE;
  292. ExposedState state = getExposedState();
  293. if (match.maybeTrue()) {
  294. residueTest = pointcut.findResidue(forShadow, state);
  295. }
  296. ShadowMatchImpl sm = new ShadowMatchImpl(match, residueTest, state, parameters);
  297. sm.setMatchingContext(this.matchContext);
  298. return sm;
  299. }
  300. /*
  301. * (non-Javadoc)
  302. *
  303. * @see org.aspectj.weaver.tools.PointcutExpression#getPointcutExpression()
  304. */
  305. public String getPointcutExpression() {
  306. return expression;
  307. }
  308. private static class HasPossibleDynamicContentVisitor extends AbstractPatternNodeVisitor {
  309. private boolean hasDynamicContent = false;
  310. public boolean hasDynamicContent() {
  311. return hasDynamicContent;
  312. }
  313. @Override
  314. public Object visit(WithinAnnotationPointcut node, Object data) {
  315. hasDynamicContent = true;
  316. return null;
  317. }
  318. @Override
  319. public Object visit(WithinCodeAnnotationPointcut node, Object data) {
  320. hasDynamicContent = true;
  321. return null;
  322. }
  323. @Override
  324. public Object visit(AnnotationPointcut node, Object data) {
  325. hasDynamicContent = true;
  326. return null;
  327. }
  328. @Override
  329. public Object visit(ArgsAnnotationPointcut node, Object data) {
  330. hasDynamicContent = true;
  331. return null;
  332. }
  333. @Override
  334. public Object visit(ArgsPointcut node, Object data) {
  335. hasDynamicContent = true;
  336. return null;
  337. }
  338. @Override
  339. public Object visit(CflowPointcut node, Object data) {
  340. hasDynamicContent = true;
  341. return null;
  342. }
  343. @Override
  344. public Object visit(IfPointcut node, Object data) {
  345. hasDynamicContent = true;
  346. return null;
  347. }
  348. @Override
  349. public Object visit(NotAnnotationTypePattern node, Object data) {
  350. return node.getNegatedPattern().accept(this, data);
  351. }
  352. @Override
  353. public Object visit(NotPointcut node, Object data) {
  354. return node.getNegatedPointcut().accept(this, data);
  355. }
  356. @Override
  357. public Object visit(ThisOrTargetAnnotationPointcut node, Object data) {
  358. hasDynamicContent = true;
  359. return null;
  360. }
  361. @Override
  362. public Object visit(ThisOrTargetPointcut node, Object data) {
  363. hasDynamicContent = true;
  364. return null;
  365. }
  366. }
  367. public static class Handler implements Member {
  368. private Class decClass;
  369. private Class exType;
  370. public Handler(Class decClass, Class exType) {
  371. this.decClass = decClass;
  372. this.exType = exType;
  373. }
  374. public int getModifiers() {
  375. return 0;
  376. }
  377. public Class getDeclaringClass() {
  378. return decClass;
  379. }
  380. public String getName() {
  381. return null;
  382. }
  383. public Class getHandledExceptionType() {
  384. return exType;
  385. }
  386. public boolean isSynthetic() {
  387. return false;
  388. }
  389. }
  390. }