package org.aspectj.weaver.ast;
+import org.aspectj.weaver.internal.tools.MatchingContextBasedTest;
+
public interface ITestVisitor {
void visit(Call call);
void visit(FieldGetCall fieldGetCall);
void visit(HasAnnotation hasAnnotation);
+ void visit(MatchingContextBasedTest matchingContextTest);
}
import org.aspectj.weaver.ast.StringConstExpr;
import org.aspectj.weaver.ast.Test;
import org.aspectj.weaver.ast.Var;
+import org.aspectj.weaver.internal.tools.MatchingContextBasedTest;
// we generate right to left, btw.
public class BcelRenderer implements ITestVisitor, IExprVisitor {
hasAnnotation.getVar().accept(this);
}
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.ast.ITestVisitor#visit(org.aspectj.weaver.internal.tools.MatchingContextBasedTest)
+ */
+ public void visit(MatchingContextBasedTest matchingContextTest) {
+ throw new UnsupportedOperationException("matching context extension not supported in bytecode weaving");
+ }
+
private InstructionList createJumpBasedOnBooleanOnStack() {
InstructionList il = new InstructionList();
if (sk == fk) {
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 2005 Contributors.
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Adrian Colyer Initial implementation
+ * ******************************************************************/
+package org.aspectj.weaver.internal.tools;
+
+import org.aspectj.weaver.ast.ITestVisitor;
+import org.aspectj.weaver.ast.Test;
+import org.aspectj.weaver.tools.MatchingContext;
+import org.aspectj.weaver.tools.ContextBasedMatcher;
+
+/**
+ * Test that uses MatchingContext to match (or not)
+ *
+ */
+public class MatchingContextBasedTest extends Test {
+
+ private final ContextBasedMatcher matcher;
+
+ public MatchingContextBasedTest(ContextBasedMatcher pc) {
+ this.matcher = pc;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.ast.Test#accept(org.aspectj.weaver.ast.ITestVisitor)
+ */
+ public void accept(ITestVisitor v) {
+ v.visit(this);
+ }
+
+ public boolean matches(MatchingContext context) {
+ return this.matcher.matchesDynamically(context);
+ }
+
+}
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 2005 Contributors.
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Adrian Colyer Initial implementation
+ * ******************************************************************/
+package org.aspectj.weaver.internal.tools;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.Map;
+import java.util.Set;
+
+import org.aspectj.util.FuzzyBoolean;
+import org.aspectj.weaver.IntMap;
+import org.aspectj.weaver.ResolvedType;
+import org.aspectj.weaver.Shadow;
+import org.aspectj.weaver.ast.Literal;
+import org.aspectj.weaver.ast.Test;
+import org.aspectj.weaver.patterns.Bindings;
+import org.aspectj.weaver.patterns.ExposedState;
+import org.aspectj.weaver.patterns.FastMatchInfo;
+import org.aspectj.weaver.patterns.IScope;
+import org.aspectj.weaver.patterns.PatternNodeVisitor;
+import org.aspectj.weaver.patterns.Pointcut;
+import org.aspectj.weaver.reflect.ReflectionShadow;
+import org.aspectj.weaver.reflect.ReflectionWorld;
+import org.aspectj.weaver.tools.ContextBasedMatcher;
+import org.aspectj.weaver.tools.MatchingContext;
+
+/**
+ * Implementation of Pointcut that is backed by a user-extension
+ * pointcut designator handler.
+ *
+ */
+public class PointcutDesignatorHandlerBasedPointcut extends Pointcut{
+
+ private final ContextBasedMatcher matcher;
+ private final ReflectionWorld world;
+
+ public PointcutDesignatorHandlerBasedPointcut(
+ ContextBasedMatcher expr,
+ ReflectionWorld world) {
+ this.matcher = expr;
+ this.world = world;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.Pointcut#getPointcutKind()
+ */
+ public byte getPointcutKind() {
+ return Pointcut.USER_EXTENSION;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.Pointcut#fastMatch(org.aspectj.weaver.patterns.FastMatchInfo)
+ */
+ public FuzzyBoolean fastMatch(FastMatchInfo info) {
+ try {
+ return FuzzyBoolean.fromBoolean(
+ this.matcher.couldMatchJoinPointsInType(
+ Class.forName(info.getType().getName(),false,world.getClassLoader()))
+ );
+ } catch (ClassNotFoundException cnfEx) {
+ return FuzzyBoolean.MAYBE;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.Pointcut#couldMatchKinds()
+ */
+ public Set couldMatchKinds() {
+ return Shadow.ALL_SHADOW_KINDS;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.Pointcut#matchInternal(org.aspectj.weaver.Shadow)
+ */
+ protected FuzzyBoolean matchInternal(Shadow shadow) {
+ if (shadow instanceof ReflectionShadow) {
+ MatchingContext context = ((ReflectionShadow)shadow).getMatchingContext();
+ org.aspectj.weaver.tools.FuzzyBoolean match =
+ this.matcher.matchesStatically(context);
+ if (match == org.aspectj.weaver.tools.FuzzyBoolean.MAYBE) {
+ return FuzzyBoolean.MAYBE;
+ } else if (match == org.aspectj.weaver.tools.FuzzyBoolean.YES) {
+ return FuzzyBoolean.YES;
+ } else if (match == org.aspectj.weaver.tools.FuzzyBoolean.NO) {
+ return FuzzyBoolean.NO;
+ }
+ }
+ throw new IllegalStateException("Can only match user-extension pcds against Reflection shadows (not BCEL)");
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.Pointcut#resolveBindings(org.aspectj.weaver.patterns.IScope, org.aspectj.weaver.patterns.Bindings)
+ */
+ protected void resolveBindings(IScope scope, Bindings bindings) {
+ // no-op
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.Pointcut#concretize1(org.aspectj.weaver.ResolvedType, org.aspectj.weaver.ResolvedType, org.aspectj.weaver.IntMap)
+ */
+ protected Pointcut concretize1(ResolvedType inAspect,
+ ResolvedType declaringType, IntMap bindings) {
+ return this;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.Pointcut#findResidueInternal(org.aspectj.weaver.Shadow, org.aspectj.weaver.patterns.ExposedState)
+ */
+ protected Test findResidueInternal(Shadow shadow, ExposedState state) {
+ if (!this.matcher.mayNeedDynamicTest()) {
+ return Literal.TRUE;
+ } else {
+ // could be more efficient here!
+ matchInternal(shadow);
+ return new MatchingContextBasedTest(this.matcher);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.Pointcut#parameterizeWith(java.util.Map)
+ */
+ public Pointcut parameterizeWith(Map typeVariableMap) {
+ return this;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PatternNode#write(java.io.DataOutputStream)
+ */
+ public void write(DataOutputStream s) throws IOException {
+ throw new UnsupportedOperationException("can't write custom pointcut designator expressions to stream");
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PatternNode#accept(org.aspectj.weaver.patterns.PatternNodeVisitor, java.lang.Object)
+ */
+ public Object accept(PatternNodeVisitor visitor, Object data) {
+ //visitor.visit(this);
+ // no-op?
+ return data;
+ }
+
+}
import org.aspectj.weaver.patterns.ThisOrTargetPointcut;
import org.aspectj.weaver.reflect.ReflectionShadow;
import org.aspectj.weaver.reflect.ShadowMatchImpl;
+import org.aspectj.weaver.tools.DefaultMatchingContext;
+import org.aspectj.weaver.tools.MatchingContext;
import org.aspectj.weaver.tools.PointcutExpression;
import org.aspectj.weaver.tools.PointcutParameter;
import org.aspectj.weaver.tools.ShadowMatch;
private Pointcut pointcut;
private String expression;
private PointcutParameter[] parameters;
+ private MatchingContext matchContext = new DefaultMatchingContext();
public PointcutExpressionImpl(Pointcut pointcut, String expression, PointcutParameter[] params, World inWorld) {
this.pointcut = pointcut;
return this.pointcut;
}
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.tools.PointcutExpression#setMatchingContext(org.aspectj.weaver.tools.MatchingContext)
+ */
+ public void setMatchingContext(MatchingContext aMatchContext) {
+ this.matchContext = aMatchContext;
+ }
+
public boolean couldMatchJoinPointsInType(Class aClass) {
return pointcut.fastMatch(new FastMatchInfo(world.resolve(aClass.getName()),null)).maybeTrue();
}
}
private ShadowMatch matchesExecution(Member aMember) {
- Shadow s = ReflectionShadow.makeExecutionShadow(world, aMember);
+ Shadow s = ReflectionShadow.makeExecutionShadow(world, aMember,this.matchContext);
ShadowMatchImpl sm = getShadowMatch(s);
sm.setSubject(aMember);
sm.setWithinCode(null);
}
public ShadowMatch matchesStaticInitialization(Class aClass) {
- Shadow s = ReflectionShadow.makeStaticInitializationShadow(world, aClass);
+ Shadow s = ReflectionShadow.makeStaticInitializationShadow(world, aClass,this.matchContext);
ShadowMatchImpl sm = getShadowMatch(s);
sm.setSubject(null);
sm.setWithinCode(null);
}
public ShadowMatch matchesAdviceExecution(Method aMethod) {
- Shadow s = ReflectionShadow.makeAdviceExecutionShadow(world, aMethod);
+ Shadow s = ReflectionShadow.makeAdviceExecutionShadow(world, aMethod,this.matchContext);
ShadowMatchImpl sm = getShadowMatch(s);
sm.setSubject(aMethod);
sm.setWithinCode(null);
}
public ShadowMatch matchesInitialization(Constructor aConstructor) {
- Shadow s = ReflectionShadow.makeInitializationShadow(world, aConstructor);
+ Shadow s = ReflectionShadow.makeInitializationShadow(world, aConstructor,this.matchContext);
ShadowMatchImpl sm = getShadowMatch(s);
sm.setSubject(aConstructor);
sm.setWithinCode(null);
}
public ShadowMatch matchesPreInitialization(Constructor aConstructor) {
- Shadow s = ReflectionShadow.makePreInitializationShadow(world, aConstructor);
+ Shadow s = ReflectionShadow.makePreInitializationShadow(world, aConstructor,this.matchContext);
ShadowMatchImpl sm = getShadowMatch(s);
sm.setSubject(aConstructor);
sm.setWithinCode(null);
}
public ShadowMatch matchesMethodCall(Method aMethod, Member withinCode) {
- Shadow s = ReflectionShadow.makeCallShadow(world, aMethod, withinCode);
+ Shadow s = ReflectionShadow.makeCallShadow(world, aMethod, withinCode,this.matchContext);
ShadowMatchImpl sm = getShadowMatch(s);
sm.setSubject(aMethod);
sm.setWithinCode(withinCode);
}
public ShadowMatch matchesMethodCall(Method aMethod, Class callerType) {
- Shadow s = ReflectionShadow.makeCallShadow(world, aMethod, callerType);
+ Shadow s = ReflectionShadow.makeCallShadow(world, aMethod, callerType,this.matchContext);
ShadowMatchImpl sm = getShadowMatch(s);
sm.setSubject(aMethod);
sm.setWithinCode(null);
}
public ShadowMatch matchesConstructorCall(Constructor aConstructor, Class callerType) {
- Shadow s = ReflectionShadow.makeCallShadow(world, aConstructor, callerType);
+ Shadow s = ReflectionShadow.makeCallShadow(world, aConstructor, callerType,this.matchContext);
ShadowMatchImpl sm = getShadowMatch(s);
sm.setSubject(aConstructor);
sm.setWithinCode(null);
}
public ShadowMatch matchesConstructorCall(Constructor aConstructor, Member withinCode) {
- Shadow s = ReflectionShadow.makeCallShadow(world, aConstructor,withinCode);
+ Shadow s = ReflectionShadow.makeCallShadow(world, aConstructor,withinCode,this.matchContext);
ShadowMatchImpl sm = getShadowMatch(s);
sm.setSubject(aConstructor);
sm.setWithinCode(withinCode);
}
public ShadowMatch matchesHandler(Class exceptionType, Class handlingType) {
- Shadow s = ReflectionShadow.makeHandlerShadow(world,exceptionType,handlingType);
+ Shadow s = ReflectionShadow.makeHandlerShadow(world,exceptionType,handlingType,this.matchContext);
ShadowMatchImpl sm = getShadowMatch(s);
sm.setSubject(null);
sm.setWithinCode(null);
}
public ShadowMatch matchesHandler(Class exceptionType, Member withinCode) {
- Shadow s = ReflectionShadow.makeHandlerShadow(world,exceptionType,withinCode);
+ Shadow s = ReflectionShadow.makeHandlerShadow(world,exceptionType,withinCode,this.matchContext);
ShadowMatchImpl sm = getShadowMatch(s);
sm.setSubject(null);
sm.setWithinCode(withinCode);
}
public ShadowMatch matchesFieldGet(Field aField, Class withinType) {
- Shadow s = ReflectionShadow.makeFieldGetShadow(world, aField, withinType);
+ Shadow s = ReflectionShadow.makeFieldGetShadow(world, aField, withinType,this.matchContext);
ShadowMatchImpl sm = getShadowMatch(s);
sm.setSubject(aField);
sm.setWithinCode(null);
}
public ShadowMatch matchesFieldGet(Field aField, Member withinCode) {
- Shadow s = ReflectionShadow.makeFieldGetShadow(world, aField, withinCode);
+ Shadow s = ReflectionShadow.makeFieldGetShadow(world, aField, withinCode,this.matchContext);
ShadowMatchImpl sm = getShadowMatch(s);
sm.setSubject(aField);
sm.setWithinCode(withinCode);
}
public ShadowMatch matchesFieldSet(Field aField, Class withinType) {
- Shadow s = ReflectionShadow.makeFieldSetShadow(world, aField, withinType);
+ Shadow s = ReflectionShadow.makeFieldSetShadow(world, aField, withinType,this.matchContext);
ShadowMatchImpl sm = getShadowMatch(s);
sm.setSubject(aField);
sm.setWithinCode(null);
}
public ShadowMatch matchesFieldSet(Field aField, Member withinCode) {
- Shadow s = ReflectionShadow.makeFieldSetShadow(world, aField, withinCode);
+ Shadow s = ReflectionShadow.makeFieldSetShadow(world, aField, withinCode,this.matchContext);
ShadowMatchImpl sm = getShadowMatch(s);
sm.setSubject(aField);
sm.setWithinCode(withinCode);
if (match.maybeTrue()) {
residueTest = pointcut.findResidue(forShadow, state);
}
- return new ShadowMatchImpl(match,residueTest,state,parameters);
+ ShadowMatchImpl sm = new ShadowMatchImpl(match,residueTest,state,parameters);
+ sm.setMatchingContext(this.matchContext);
+ return sm;
}
/* (non-Javadoc)
package org.aspectj.weaver.patterns;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
+import java.util.Set;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.Member;
import org.aspectj.weaver.Shadow;
import org.aspectj.weaver.UnresolvedType;
+import org.aspectj.weaver.World;
+import org.aspectj.weaver.internal.tools.PointcutDesignatorHandlerBasedPointcut;
+import org.aspectj.weaver.reflect.ReflectionWorld;
+import org.aspectj.weaver.tools.ContextBasedMatcher;
+import org.aspectj.weaver.tools.PointcutDesignatorHandler;
//XXX doesn't handle errors for extra tokens very well (sometimes ignores)
public class PatternParser {
/** not thread-safe, but this class is not intended to be... */
private boolean allowHasTypePatterns = false;
+
+ /** extension handlers used in weaver tools API only */
+ private Set pointcutDesignatorHandlers = Collections.EMPTY_SET;
+ private ReflectionWorld world;
/**
* Constructor for PatternParser.
this.tokenSource = tokenSource;
this.sourceContext = tokenSource.getSourceContext();
}
+
+ /** only used by weaver tools API */
+ public void setPointcutDesignatorHandlers(Set handlers, ReflectionWorld world) {
+ this.pointcutDesignatorHandlers = handlers;
+ this.world = world;
+ }
public PerClause maybeParsePerClause() {
IToken tok = tokenSource.peek();
// TODO - Alex has some token stuff going on here to get a readable name in place of ""...
p = new IfPointcut("");
}
- }
+ }
else {
- tokenSource.setIndex(start);
- p = parseReferencePointcut();
+ boolean matchedByExtensionDesignator = false;
+ // see if a registered handler wants to parse it, otherwise
+ // treat as a reference pointcut
+ for (Iterator iter = this.pointcutDesignatorHandlers.iterator(); iter.hasNext();) {
+ PointcutDesignatorHandler pcd = (PointcutDesignatorHandler) iter.next();
+ if (pcd.getDesignatorName().equals(kind)) {
+ p = parseDesignatorPointcut(pcd);
+ matchedByExtensionDesignator = true;
+ }
+
+ }
+ if (!matchedByExtensionDesignator) {
+ tokenSource.setIndex(start);
+ p = parseReferencePointcut();
+ }
}
return p;
}
TypePatternList arguments = parseArgumentsPattern();
return new ReferencePointcut(onType, name.maybeGetSimpleName(), arguments);
}
+
+ private Pointcut parseDesignatorPointcut(PointcutDesignatorHandler pcdHandler) {
+ eat("(");
+ int parenCount = 1;
+ StringBuffer pointcutBody = new StringBuffer();
+ while (parenCount > 0) {
+ if (maybeEat("(")) {
+ parenCount++;
+ pointcutBody.append("(");
+ } else if (maybeEat(")")) {
+ parenCount--;
+ if (parenCount > 0) {
+ pointcutBody.append(")");
+ }
+ } else {
+ pointcutBody.append(nextToken().getString());
+ }
+ }
+ ContextBasedMatcher pcExpr = pcdHandler.parse(pointcutBody.toString());
+ return new PointcutDesignatorHandlerBasedPointcut(pcExpr,world);
+ }
public List parseDottedIdentifier() {
public static final byte NONE = 20; // DO NOT CHANGE OR REORDER THIS SEQUENCE, THIS VALUE CAN BE PUT OUT BY ASPECTJ1.2.1
public static final byte ATARGS = 21;
+ public static final byte USER_EXTENSION = 22;
public byte getPointcutKind() { return pointcutKind; }
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.World;
import org.aspectj.weaver.ast.Var;
+import org.aspectj.weaver.tools.MatchingContext;
/**
* @author colyer
*/
public class ReflectionShadow extends Shadow {
- private World world;
- private ResolvedType enclosingType;
- private ResolvedMember enclosingMember;
+ private final World world;
+ private final ResolvedType enclosingType;
+ private final ResolvedMember enclosingMember;
+ private final MatchingContext matchContext;
private Var thisVar = null;
private Var targetVar = null;
private Var[] argsVars = null;
private Map annotationVar = new HashMap();
private AnnotationFinder annotationFinder;
- public static Shadow makeExecutionShadow(World inWorld, java.lang.reflect.Member forMethod) {
+ public static Shadow makeExecutionShadow(World inWorld, java.lang.reflect.Member forMethod, MatchingContext withContext) {
Kind kind = (forMethod instanceof Method) ? Shadow.MethodExecution : Shadow.ConstructorExecution;
Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(forMethod, inWorld);
ResolvedType enclosingType = signature.getDeclaringType().resolve(inWorld);
- return new ReflectionShadow(inWorld,kind,signature,null,enclosingType,null);
+ return new ReflectionShadow(inWorld,kind,signature,null,enclosingType,null,withContext);
}
- public static Shadow makeAdviceExecutionShadow(World inWorld, java.lang.reflect.Method forMethod) {
+ public static Shadow makeAdviceExecutionShadow(World inWorld, java.lang.reflect.Method forMethod, MatchingContext withContext) {
Kind kind = Shadow.AdviceExecution;
Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedAdviceMember(forMethod, inWorld);
ResolvedType enclosingType = signature.getDeclaringType().resolve(inWorld);
- return new ReflectionShadow(inWorld,kind,signature,null,enclosingType,null);
+ return new ReflectionShadow(inWorld,kind,signature,null,enclosingType,null,withContext);
}
- public static Shadow makeCallShadow(World inWorld, java.lang.reflect.Member aMember, java.lang.reflect.Member withinCode) {
- Shadow enclosingShadow = makeExecutionShadow(inWorld,withinCode);
+ public static Shadow makeCallShadow(World inWorld, java.lang.reflect.Member aMember, java.lang.reflect.Member withinCode, MatchingContext withContext) {
+ Shadow enclosingShadow = makeExecutionShadow(inWorld,withinCode,withContext);
Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(aMember, inWorld);
ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(withinCode, inWorld);
ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld);
Kind kind = aMember instanceof Method ? Shadow.MethodCall : Shadow.ConstructorCall;
- return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember);
+ return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember,withContext);
}
- public static Shadow makeCallShadow(World inWorld, java.lang.reflect.Member aMember, Class thisClass) {
- Shadow enclosingShadow = makeStaticInitializationShadow(inWorld, thisClass);
+ public static Shadow makeCallShadow(World inWorld, java.lang.reflect.Member aMember, Class thisClass, MatchingContext withContext) {
+ Shadow enclosingShadow = makeStaticInitializationShadow(inWorld, thisClass,withContext);
Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(aMember, inWorld);
ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createStaticInitMember(thisClass, inWorld);
ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld);
Kind kind = aMember instanceof Method ? Shadow.MethodCall : Shadow.ConstructorCall;
- return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember);
+ return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember,withContext);
}
- public static Shadow makeStaticInitializationShadow(World inWorld, Class forType) {
+ public static Shadow makeStaticInitializationShadow(World inWorld, Class forType, MatchingContext withContext) {
Member signature = ReflectionBasedReferenceTypeDelegateFactory.createStaticInitMember(forType, inWorld);
ResolvedType enclosingType = signature.getDeclaringType().resolve(inWorld);
Kind kind = Shadow.StaticInitialization;
- return new ReflectionShadow(inWorld,kind,signature,null,enclosingType,null);
+ return new ReflectionShadow(inWorld,kind,signature,null,enclosingType,null,withContext);
}
- public static Shadow makePreInitializationShadow(World inWorld, Constructor forConstructor) {
+ public static Shadow makePreInitializationShadow(World inWorld, Constructor forConstructor, MatchingContext withContext) {
Kind kind = Shadow.PreInitialization;
Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(forConstructor, inWorld);
ResolvedType enclosingType = signature.getDeclaringType().resolve(inWorld);
- return new ReflectionShadow(inWorld,kind,signature,null,enclosingType,null);
+ return new ReflectionShadow(inWorld,kind,signature,null,enclosingType,null,withContext);
}
- public static Shadow makeInitializationShadow(World inWorld, Constructor forConstructor) {
+ public static Shadow makeInitializationShadow(World inWorld, Constructor forConstructor, MatchingContext withContext) {
Kind kind = Shadow.Initialization;
Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(forConstructor, inWorld);
ResolvedType enclosingType = signature.getDeclaringType().resolve(inWorld);
- return new ReflectionShadow(inWorld,kind,signature,null,enclosingType,null);
+ return new ReflectionShadow(inWorld,kind,signature,null,enclosingType,null,withContext);
}
- public static Shadow makeHandlerShadow(World inWorld, Class exceptionType, Class withinType) {
+ public static Shadow makeHandlerShadow(World inWorld, Class exceptionType, Class withinType, MatchingContext withContext) {
Kind kind = Shadow.ExceptionHandler;
- Shadow enclosingShadow = makeStaticInitializationShadow(inWorld, withinType);
+ Shadow enclosingShadow = makeStaticInitializationShadow(inWorld, withinType,withContext);
Member signature = ReflectionBasedReferenceTypeDelegateFactory.createHandlerMember(exceptionType, withinType, inWorld);
ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createStaticInitMember(withinType, inWorld);
ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld);
- return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember);
+ return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember,withContext);
}
- public static Shadow makeHandlerShadow(World inWorld, Class exceptionType, java.lang.reflect.Member withinCode) {
+ public static Shadow makeHandlerShadow(World inWorld, Class exceptionType, java.lang.reflect.Member withinCode, MatchingContext withContext) {
Kind kind = Shadow.ExceptionHandler;
- Shadow enclosingShadow = makeExecutionShadow(inWorld, withinCode);
+ Shadow enclosingShadow = makeExecutionShadow(inWorld, withinCode,withContext);
Member signature = ReflectionBasedReferenceTypeDelegateFactory.createHandlerMember(exceptionType, withinCode.getDeclaringClass(), inWorld);
ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(withinCode, inWorld);
ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld);
- return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember);
+ return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember,withContext);
}
- public static Shadow makeFieldGetShadow(World inWorld, Field forField, Class callerType) {
- Shadow enclosingShadow = makeStaticInitializationShadow(inWorld, callerType);
+ public static Shadow makeFieldGetShadow(World inWorld, Field forField, Class callerType, MatchingContext withContext) {
+ Shadow enclosingShadow = makeStaticInitializationShadow(inWorld, callerType,withContext);
Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedField(forField, inWorld);
ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createStaticInitMember(callerType, inWorld);
ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld);
Kind kind = Shadow.FieldGet;
- return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember);
+ return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember,withContext);
}
- public static Shadow makeFieldGetShadow(World inWorld, Field forField, java.lang.reflect.Member inMember) {
- Shadow enclosingShadow = makeExecutionShadow(inWorld,inMember);
+ public static Shadow makeFieldGetShadow(World inWorld, Field forField, java.lang.reflect.Member inMember, MatchingContext withContext) {
+ Shadow enclosingShadow = makeExecutionShadow(inWorld,inMember,withContext);
Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedField(forField, inWorld);
ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(inMember, inWorld);
ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld);
Kind kind = Shadow.FieldGet;
- return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember);
+ return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember,withContext);
}
- public static Shadow makeFieldSetShadow(World inWorld, Field forField, Class callerType) {
- Shadow enclosingShadow = makeStaticInitializationShadow(inWorld, callerType);
+ public static Shadow makeFieldSetShadow(World inWorld, Field forField, Class callerType, MatchingContext withContext) {
+ Shadow enclosingShadow = makeStaticInitializationShadow(inWorld, callerType, withContext);
Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedField(forField, inWorld);
ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createStaticInitMember(callerType, inWorld);
ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld);
Kind kind = Shadow.FieldSet;
- return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember);
+ return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember,withContext);
}
- public static Shadow makeFieldSetShadow(World inWorld, Field forField, java.lang.reflect.Member inMember) {
- Shadow enclosingShadow = makeExecutionShadow(inWorld,inMember);
+ public static Shadow makeFieldSetShadow(World inWorld, Field forField, java.lang.reflect.Member inMember, MatchingContext withContext) {
+ Shadow enclosingShadow = makeExecutionShadow(inWorld,inMember,withContext);
Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedField(forField, inWorld);
ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(inMember, inWorld);
ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld);
Kind kind = Shadow.FieldSet;
- return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember);
+ return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember,withContext);
}
- public ReflectionShadow(World world, Kind kind, Member signature, Shadow enclosingShadow, ResolvedType enclosingType, ResolvedMember enclosingMember) {
+ public ReflectionShadow(World world, Kind kind, Member signature, Shadow enclosingShadow, ResolvedType enclosingType, ResolvedMember enclosingMember, MatchingContext withContext) {
super(kind,signature,enclosingShadow);
this.world = world;
this.enclosingType = enclosingType;
this.enclosingMember = enclosingMember;
+ this.matchContext = withContext;
if (world instanceof ReflectionWorld) {
this.annotationFinder = ((ReflectionWorld)world).getAnnotationFinder();
}
return null;
}
+ public MatchingContext getMatchingContext() {
+ return this.matchContext;
+ }
}
import org.aspectj.weaver.ast.Or;
import org.aspectj.weaver.ast.Test;
import org.aspectj.weaver.ast.Var;
+import org.aspectj.weaver.internal.tools.MatchingContextBasedTest;
import org.aspectj.weaver.patterns.ExposedState;
+import org.aspectj.weaver.tools.DefaultMatchingContext;
import org.aspectj.weaver.tools.JoinPointMatch;
+import org.aspectj.weaver.tools.MatchingContext;
import org.aspectj.weaver.tools.PointcutParameter;
import org.aspectj.weaver.tools.ShadowMatch;
private Member withinCode;
private Member subject;
private Class withinType;
+ private MatchingContext matchContext = new DefaultMatchingContext();
public ShadowMatchImpl(FuzzyBoolean match, Test test, ExposedState state, PointcutParameter[] params) {
this.match = match;
public JoinPointMatch matchesJoinPoint(Object thisObject, Object targetObject, Object[] args) {
if (neverMatches()) return JoinPointMatchImpl.NO_MATCH;
- if (new RuntimeTestEvaluator(residualTest,thisObject,targetObject,args).matches()) {
+ if (new RuntimeTestEvaluator(residualTest,thisObject,targetObject,args,this.matchContext).matches()) {
return new JoinPointMatchImpl(getPointcutParameters(thisObject,targetObject,args));
} else {
return JoinPointMatchImpl.NO_MATCH;
}
}
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.tools.ShadowMatch#setMatchingContext(org.aspectj.weaver.tools.MatchingContext)
+ */
+ public void setMatchingContext(MatchingContext aMatchContext) {
+ this.matchContext = aMatchContext;
+ }
private PointcutParameter[] getPointcutParameters(Object thisObject, Object targetObject, Object[] args) {
Var[] vars = state.vars;
private static class RuntimeTestEvaluator implements ITestVisitor {
private boolean matches = true;
- private Test test;
- private Object thisObject;
- private Object targetObject;
- private Object[] args;
+ private final Test test;
+ private final Object thisObject;
+ private final Object targetObject;
+ private final Object[] args;
+ private final MatchingContext matchContext;
+
- public RuntimeTestEvaluator(Test aTest,Object thisObject, Object targetObject, Object[] args) {
+ public RuntimeTestEvaluator(Test aTest,Object thisObject, Object targetObject, Object[] args, MatchingContext context) {
this.test = aTest;
this.thisObject = thisObject;
this.targetObject = targetObject;
this.args = args;
+ this.matchContext = context;
}
public boolean matches() {
public void visit(And e) {
boolean leftMatches =
- new RuntimeTestEvaluator(e.getLeft(),thisObject,targetObject,args).matches();
+ new RuntimeTestEvaluator(e.getLeft(),thisObject,targetObject,args,matchContext).matches();
if (!leftMatches) {
matches = false;
} else {
- matches = new RuntimeTestEvaluator(e.getRight(),thisObject,targetObject,args).matches();
+ matches = new RuntimeTestEvaluator(e.getRight(),thisObject,targetObject,args,matchContext).matches();
}
}
ResolvedType actualType = world.resolve(value.getClass().getName());
matches = desiredType.isAssignableFrom(actualType);
}
+
+ public void visit(MatchingContextBasedTest matchingContextTest) {
+ matches = matchingContextTest.matches(this.matchContext);
+ }
public void visit(Not not) {
- matches = ! new RuntimeTestEvaluator(not.getBody(),thisObject,targetObject,args).matches();
+ matches = ! new RuntimeTestEvaluator(not.getBody(),thisObject,targetObject,args,matchContext).matches();
}
public void visit(Or or) {
boolean leftMatches =
- new RuntimeTestEvaluator(or.getLeft(),thisObject,targetObject,args).matches();
+ new RuntimeTestEvaluator(or.getLeft(),thisObject,targetObject,args,matchContext).matches();
if (leftMatches) {
matches = true;
} else {
- matches = new RuntimeTestEvaluator(or.getRight(),thisObject,targetObject,args).matches();
+ matches = new RuntimeTestEvaluator(or.getRight(),thisObject,targetObject,args,matchContext).matches();
}
}
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 2005 Contributors.
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Adrian Colyer Initial implementation
+ * ******************************************************************/
+package org.aspectj.weaver.tools;
+
+/**
+ * Pointcut expression interface for pointcut
+ * expressions returned by a
+ * PointcutDesignatorHandler. Provides an additional
+ * matching method for matching based on context
+ * information over and above that normally used
+ * by AspectJ.
+ *
+ * @see MatchingContext
+ *
+ */
+public interface ContextBasedMatcher {
+
+ /**
+ * return true iff this matcher could ever match
+ * a join point in the given type
+ */
+ boolean couldMatchJoinPointsInType(Class aClass);
+
+ /**
+ * return true if matchesStatically can ever return
+ * FuzzyBoolean.MAYBE (necessitating a per-join point test
+ * to determine matching at a given join point).
+ */
+ boolean mayNeedDynamicTest();
+
+ /**
+ * Return FuzzyBoolean.YES if a join point with the given
+ * matching context is always matched.
+ * Return FuzzyBoolean.NO if a join point with the given
+ * matching context is never matched.
+ * Return FuzzyBoolean.MAYBE if a match cannot be determined
+ * statically (whilst generating a ShadowMatch), and must
+ * be determined on a per-join point basis.
+ */
+ FuzzyBoolean matchesStatically(MatchingContext matchContext);
+
+ /**
+ * Called during processing of ShadowMatch.matchesJoinPoint
+ * when matchesStatically returned FuzzyBoolean.MAYBE.
+ */
+ boolean matchesDynamically(MatchingContext matchContext);
+}
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 2005 Contributors.
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Adrian Colyer Initial implementation
+ * ******************************************************************/
+package org.aspectj.weaver.tools;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Default implementation of MatchingContext, backed
+ * by a Map.
+ */
+public class DefaultMatchingContext implements MatchingContext {
+
+ private Map contextMap = new HashMap();
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.tools.MatchingContext#hasContextParameter(java.lang.String)
+ */
+ public boolean hasContextBinding(String contextParameterName) {
+ return this.contextMap.containsKey(contextParameterName);
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.tools.MatchingContext#get(java.lang.String)
+ */
+ public Object getBinding(String contextParameterName) {
+ return this.contextMap.get(contextParameterName);
+ }
+
+ /**
+ * Add a context binding with the given name and value
+ * @param name
+ * @param value
+ */
+ public void addContextBinding(String name, Object value) {
+ this.contextMap.put(name, value);
+ }
+
+ /**
+ * Remove the context binding with the given name
+ * @param name
+ */
+ public void removeContextBinding(String name) {
+ this.contextMap.remove(name);
+ }
+
+}
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 2005 Contributors.
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Adrian Colyer Initial implementation
+ * ******************************************************************/
+package org.aspectj.weaver.tools;
+
+/**
+ * When extending AspectJ's pointcut parsing and
+ * matching with custom PointcutDesignatorHandlers,
+ * it may be necessary to match based on context information
+ * at a join point not exposed simply by java.lang.reflect
+ * member information or argument values. The matching context
+ * interface provides an extension point for the specification
+ * of additional shadow and join point context that can be
+ * taken into account during the matching process.
+ *
+ * @see DefaultMatchingContext
+ */
+public interface MatchingContext {
+
+ /**
+ * Returns true iff this matching context has a defined
+ * binding for the given context parameter.
+ * @param contextParameterName
+ */
+ boolean hasContextBinding(String contextParameterName);
+
+ /**
+ * returns the binding associated with the
+ * given context parameter name (or null if
+ * there is no such context).
+ * @param contextParameterName
+ * @return
+ */
+ Object getBinding(String contextParameterName);
+}
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 2005 Contributors.
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Adrian Colyer Initial implementation
+ * ******************************************************************/
+package org.aspectj.weaver.tools;
+
+
+/**
+ * The PointcutDesignator interface allows extension of the
+ * AspectJ pointcut language so that third-party tools integrating
+ * with AspectJ can add easily their own custom
+ * domain-specific designators and have them interoperate seamlessly
+ * with the standard AspectJ designators.
+ *
+ * A pointcut designator can only be used for matching, not for
+ * binding.
+ */
+public interface PointcutDesignatorHandler {
+
+ /**
+ * The name of this pointcut designator. For example,
+ * if this designator handles a "bean(<NamePattern>)
+ * format designator, this method would return "bean".
+ * @return
+ */
+ String getDesignatorName() ;
+
+ /**
+ * Parse the given expression string
+ * and return a ContextBasedMatcher that can be used
+ * for matching.
+ * @param expression the body of the pointcut expression.
+ * For example, given the expression "bean(*DAO)" the parse
+ * method will be called with the argument "*DAO".
+ * @return a pointcut expression that can be used for
+ * matching.
+ * @throws IllegalArgumentException if the expression
+ * is ill-formed.
+ */
+ ContextBasedMatcher parse(String expression);
+
+}
*/
public interface PointcutExpression {
+ /**
+ * Set the matching context to be used for
+ * subsequent calls to match.
+ * @see MatchingContext
+ */
+ void setMatchingContext(MatchingContext aMatchContext);
+
/**
* Determine whether or not this pointcut could ever match a join point in the given class.
* @param aClass the candidate class
*/
public class PointcutParser {
- private World world;
+ private ReflectionWorld world;
private ClassLoader classLoader;
private Set supportedPrimitives;
+ private Set pointcutDesignators = new HashSet();
/**
* @return a Set containing every PointcutPrimitive except
getWorld().getLint().setFromProperties(properties);
}
+ /**
+ * Register a new pointcut designator handler with this parser.
+ * This provides an extension mechansim for the integration of
+ * domain-specific pointcut designators with the AspectJ
+ * pointcut language.
+ * @param designatorHandler
+ */
+ public void registerPointcutDesignatorHandler(PointcutDesignatorHandler designatorHandler) {
+ this.pointcutDesignators.add(designatorHandler);
+ }
+
+ /**
+ * Create a pointcut parameter of the given name and type.
+ * @param name
+ * @param type
+ * @return
+ */
public PointcutParameter createPointcutParameter(String name, Class type) {
return new PointcutParameterImpl(name,type);
}
throws UnsupportedPointcutPrimitiveException, IllegalArgumentException {
PointcutExpressionImpl pcExpr = null;
try {
- Pointcut pc = new PatternParser(expression).parsePointcut();
+ PatternParser parser = new PatternParser(expression);
+ parser.setPointcutDesignatorHandlers(pointcutDesignators, world);
+ Pointcut pc = parser.parsePointcut();
validateAgainstSupportedPrimitives(pc,expression);
IScope resolutionScope = buildResolutionScope((inScope == null ? Object.class : inScope),formalParameters);
pc = pc.resolve(resolutionScope);
if (!supportedPrimitives.contains(PointcutPrimitive.REFERENCE))
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.REFERENCE);
break;
+ case Pointcut.USER_EXTENSION:
+ // always ok...
+ break;
case Pointcut.NONE: // deliberate fall-through
default:
throw new IllegalArgumentException("Unknown pointcut kind: " + pc.getPointcutKind());
* @return
*/
JoinPointMatch matchesJoinPoint(Object thisObject, Object targetObject, Object[] args);
+
+ /**
+ * Set a matching context to be used when matching
+ * join points.
+ * @see MatchingContext
+ */
+ void setMatchingContext(MatchingContext aMatchContext);
}
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 2005 Contributors.
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Adrian Colyer Initial implementation
+ * ******************************************************************/
+package org.aspectj.weaver.tools;
+
+import junit.framework.TestCase;
+
+/**
+ * @author Adrian
+ *
+ */
+public class PointcutDesignatorHandlerTests extends TestCase {
+
+ public void testParseWithoutHandler() {
+ try {
+ PointcutParser
+ .getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution()
+ .parsePointcutExpression("bean(service.*");
+ fail("should not be able to parse bean(service.*)");
+ } catch(IllegalArgumentException ex) {
+ assertTrue("contains bean",ex.getMessage().contains("bean"));
+ }
+ }
+
+ public void testParseWithHandler() {
+ PointcutParser parser = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution();
+ BeanDesignatorHandler beanHandler = new BeanDesignatorHandler();
+ parser.registerPointcutDesignatorHandler(beanHandler);
+ parser.parsePointcutExpression("bean(service.*)");
+ assertEquals("service.*",beanHandler.getExpressionLastAskedToParse());
+ }
+
+ public void testStaticMatch() throws Exception {
+ PointcutParser parser = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution();
+ BeanDesignatorHandler beanHandler = new BeanDesignatorHandler();
+ parser.registerPointcutDesignatorHandler(beanHandler);
+ PointcutExpression pc = parser.parsePointcutExpression("bean(myBean)");
+ DefaultMatchingContext context = new DefaultMatchingContext();
+ context.addContextBinding("beanName","myBean");
+ pc.setMatchingContext(context);
+ ShadowMatch sm = pc.matchesMethodExecution(Object.class.getMethod("toString",new Class[0]));
+ assertTrue(sm.alwaysMatches());
+ context.addContextBinding("beanName", "notMyBean");
+ sm = pc.matchesMethodExecution(Object.class.getMethod("toString",new Class[0]));
+ assertTrue(sm.neverMatches());
+ }
+
+ public void testDynamicMatch() throws Exception {
+ PointcutParser parser = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution();
+ BeanDesignatorHandler beanHandler = new BeanDesignatorHandler();
+ beanHandler.simulateDynamicTest = true;
+ parser.registerPointcutDesignatorHandler(beanHandler);
+ PointcutExpression pc = parser.parsePointcutExpression("bean(myBean)");
+ ShadowMatch sm = pc.matchesMethodExecution(Object.class.getMethod("toString",new Class[0]));
+ DefaultMatchingContext context = new DefaultMatchingContext();
+ assertTrue(sm.maybeMatches());
+ assertFalse(sm.alwaysMatches());
+ assertFalse(sm.neverMatches());
+ context.addContextBinding("beanName","myBean");
+ sm.setMatchingContext(context);
+ assertTrue(sm.matchesJoinPoint(null, null, null).matches());
+ context.addContextBinding("beanName", "notMyBean");
+ assertFalse(sm.matchesJoinPoint(null, null, null).matches());
+ }
+
+
+
+ private class BeanDesignatorHandler implements PointcutDesignatorHandler {
+
+ private String askedToParse;
+ public boolean simulateDynamicTest = false;
+
+ public String getDesignatorName() {
+ return "bean";
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.tools.PointcutDesignatorHandler#parse(java.lang.String)
+ */
+ public ContextBasedMatcher parse(String expression) {
+ this.askedToParse = expression;
+ return new BeanPointcutExpression(expression,this.simulateDynamicTest);
+ }
+
+ public String getExpressionLastAskedToParse() {
+ return this.askedToParse;
+ }
+ }
+
+ private class BeanPointcutExpression implements ContextBasedMatcher {
+
+ private final String beanNamePattern;
+ private final boolean simulateDynamicTest;
+
+ public BeanPointcutExpression(String beanNamePattern, boolean simulateDynamicTest) {
+ this.beanNamePattern = beanNamePattern;
+ this.simulateDynamicTest = simulateDynamicTest;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.tools.ContextBasedMatcher#couldMatchJoinPointsInType(java.lang.Class)
+ */
+ public boolean couldMatchJoinPointsInType(Class aClass) {
+ return true;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.tools.ContextBasedMatcher#mayNeedDynamicTest()
+ */
+ public boolean mayNeedDynamicTest() {
+ return this.simulateDynamicTest;
+ }
+
+
+ public FuzzyBoolean matchesStatically(MatchingContext matchContext) {
+ if (this.simulateDynamicTest) return FuzzyBoolean.MAYBE;
+ if (this.beanNamePattern.equals(matchContext.getBinding("beanName"))) {
+ return FuzzyBoolean.YES;
+ } else {
+ return FuzzyBoolean.NO;
+ }
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.tools.ContextBasedMatcher#matchesDynamically(org.aspectj.weaver.tools.MatchingContext)
+ */
+ public boolean matchesDynamically(MatchingContext matchContext) {
+ return this.beanNamePattern.equals(matchContext.getBinding("beanName"));
+ }
+ }
+}
\ No newline at end of file
suite.addTestSuite(PointcutParserTest.class);
suite.addTestSuite(PointcutExpressionTest.class);
suite.addTestSuite(TypePatternMatcherTest.class);
+ suite.addTestSuite(PointcutDesignatorHandlerTests.class);
//$JUnit-END$
return suite;
}