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.

StandardShadowMatchImpl.java 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  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.reflect;
  13. import org.aspectj.util.FuzzyBoolean;
  14. import org.aspectj.weaver.ResolvedMember;
  15. import org.aspectj.weaver.ResolvedType;
  16. import org.aspectj.weaver.World;
  17. import org.aspectj.weaver.ast.And;
  18. import org.aspectj.weaver.ast.Call;
  19. import org.aspectj.weaver.ast.FieldGetCall;
  20. import org.aspectj.weaver.ast.HasAnnotation;
  21. import org.aspectj.weaver.ast.ITestVisitor;
  22. import org.aspectj.weaver.ast.Instanceof;
  23. import org.aspectj.weaver.ast.Literal;
  24. import org.aspectj.weaver.ast.Not;
  25. import org.aspectj.weaver.ast.Or;
  26. import org.aspectj.weaver.ast.Test;
  27. import org.aspectj.weaver.internal.tools.MatchingContextBasedTest;
  28. import org.aspectj.weaver.patterns.ExposedState;
  29. import org.aspectj.weaver.tools.DefaultMatchingContext;
  30. import org.aspectj.weaver.tools.JoinPointMatch;
  31. import org.aspectj.weaver.tools.MatchingContext;
  32. import org.aspectj.weaver.tools.PointcutParameter;
  33. import org.aspectj.weaver.tools.ShadowMatch;
  34. /**
  35. * @author colyer Implementation of ShadowMatch for reflection based worlds.
  36. */
  37. public class StandardShadowMatchImpl implements ShadowMatch {
  38. private FuzzyBoolean match;
  39. private ExposedState state;
  40. private Test residualTest;
  41. private PointcutParameter[] params;
  42. private ResolvedMember withinCode;
  43. private ResolvedMember subject;
  44. private ResolvedType withinType;
  45. private MatchingContext matchContext = new DefaultMatchingContext();
  46. public StandardShadowMatchImpl(FuzzyBoolean match, Test test, ExposedState state, PointcutParameter[] params) {
  47. this.match = match;
  48. this.residualTest = test;
  49. this.state = state;
  50. this.params = params;
  51. }
  52. public void setWithinCode(ResolvedMember aMember) {
  53. this.withinCode = aMember;
  54. }
  55. public void setSubject(ResolvedMember aMember) {
  56. this.subject = aMember;
  57. }
  58. public void setWithinType(ResolvedType aClass) {
  59. this.withinType = aClass;
  60. }
  61. public boolean alwaysMatches() {
  62. return match.alwaysTrue();
  63. }
  64. public boolean maybeMatches() {
  65. return match.maybeTrue();
  66. }
  67. public boolean neverMatches() {
  68. return match.alwaysFalse();
  69. }
  70. public JoinPointMatch matchesJoinPoint(Object thisObject, Object targetObject, Object[] args) {
  71. if (neverMatches())
  72. return JoinPointMatchImpl.NO_MATCH;
  73. if (new RuntimeTestEvaluator(residualTest, thisObject, targetObject, args, this.matchContext).matches()) {
  74. return new JoinPointMatchImpl(getPointcutParameters(thisObject, targetObject, args));
  75. } else {
  76. return JoinPointMatchImpl.NO_MATCH;
  77. }
  78. }
  79. /*
  80. * (non-Javadoc)
  81. *
  82. * @see org.aspectj.weaver.tools.ShadowMatch#setMatchingContext(org.aspectj.weaver.tools.MatchingContext)
  83. */
  84. public void setMatchingContext(MatchingContext aMatchContext) {
  85. this.matchContext = aMatchContext;
  86. }
  87. private PointcutParameter[] getPointcutParameters(Object thisObject, Object targetObject, Object[] args) {
  88. // Var[] vars = state.vars;
  89. // PointcutParameterImpl[] bindings = new PointcutParameterImpl[params.length];
  90. // for (int i = 0; i < bindings.length; i++) {
  91. // bindings[i] = new PointcutParameterImpl(params[i].getName(), params[i].getType());
  92. // bindings[i].setBinding(((ReflectionVar) vars[i]).getBindingAtJoinPoint(thisObject, targetObject, args, subject,
  93. // withinCode, withinType));
  94. // }
  95. // return bindings;
  96. return null;
  97. }
  98. private static class RuntimeTestEvaluator implements ITestVisitor {
  99. private boolean matches = true;
  100. private final Test test;
  101. private final Object thisObject;
  102. private final Object targetObject;
  103. private final Object[] args;
  104. private final MatchingContext matchContext;
  105. public RuntimeTestEvaluator(Test aTest, Object thisObject, Object targetObject, Object[] args, MatchingContext context) {
  106. this.test = aTest;
  107. this.thisObject = thisObject;
  108. this.targetObject = targetObject;
  109. this.args = args;
  110. this.matchContext = context;
  111. }
  112. public boolean matches() {
  113. test.accept(this);
  114. return matches;
  115. }
  116. public void visit(And e) {
  117. boolean leftMatches = new RuntimeTestEvaluator(e.getLeft(), thisObject, targetObject, args, matchContext).matches();
  118. if (!leftMatches) {
  119. matches = false;
  120. } else {
  121. matches = new RuntimeTestEvaluator(e.getRight(), thisObject, targetObject, args, matchContext).matches();
  122. }
  123. }
  124. public void visit(Instanceof i) {
  125. ReflectionVar v = (ReflectionVar) i.getVar();
  126. Object value = v.getBindingAtJoinPoint(thisObject, targetObject, args);
  127. World world = v.getType().getWorld();
  128. ResolvedType desiredType = i.getType().resolve(world);
  129. ResolvedType actualType = world.resolve(value.getClass().getName());
  130. matches = desiredType.isAssignableFrom(actualType);
  131. }
  132. public void visit(MatchingContextBasedTest matchingContextTest) {
  133. matches = matchingContextTest.matches(this.matchContext);
  134. }
  135. public void visit(Not not) {
  136. matches = !new RuntimeTestEvaluator(not.getBody(), thisObject, targetObject, args, matchContext).matches();
  137. }
  138. public void visit(Or or) {
  139. boolean leftMatches = new RuntimeTestEvaluator(or.getLeft(), thisObject, targetObject, args, matchContext).matches();
  140. if (leftMatches) {
  141. matches = true;
  142. } else {
  143. matches = new RuntimeTestEvaluator(or.getRight(), thisObject, targetObject, args, matchContext).matches();
  144. }
  145. }
  146. public void visit(Literal literal) {
  147. if (literal == Literal.FALSE) {
  148. matches = false;
  149. } else {
  150. matches = true;
  151. }
  152. }
  153. public void visit(Call call) {
  154. throw new UnsupportedOperationException("Can't evaluate call test at runtime");
  155. }
  156. public void visit(FieldGetCall fieldGetCall) {
  157. throw new UnsupportedOperationException("Can't evaluate fieldGetCall test at runtime");
  158. }
  159. public void visit(HasAnnotation hasAnnotation) {
  160. ReflectionVar v = (ReflectionVar) hasAnnotation.getVar();
  161. Object value = v.getBindingAtJoinPoint(thisObject, targetObject, args);
  162. World world = v.getType().getWorld();
  163. ResolvedType actualVarType = world.resolve(value.getClass().getName());
  164. ResolvedType requiredAnnotationType = hasAnnotation.getAnnotationType().resolve(world);
  165. matches = actualVarType.hasAnnotation(requiredAnnotationType);
  166. }
  167. }
  168. }