<?xml version="1.0" encoding="UTF-8"?> | |||||
<classpath> | |||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> | |||||
<classpathentry kind="src" path="java5-src"/> | |||||
<classpathentry kind="src" path="java5-testsrc"/> | |||||
<classpathentry sourcepath="/lib/bcel/bcel-src.zip" kind="lib" path="/lib/bcel/bcel.jar"/> | |||||
<classpathentry combineaccessrules="false" kind="src" path="/weaver"/> | |||||
<classpathentry combineaccessrules="false" kind="src" path="/bridge"/> | |||||
<classpathentry combineaccessrules="false" kind="src" path="/runtime"/> | |||||
<classpathentry combineaccessrules="false" kind="src" path="/testing-util"/> | |||||
<classpathentry combineaccessrules="false" kind="src" path="/util"/> | |||||
<classpathentry combineaccessrules="false" kind="src" path="/aspectj5rt"/> | |||||
<classpathentry sourcepath="/lib/junit/junit-src.jar" kind="lib" path="/lib/junit/junit.jar"/> | |||||
<classpathentry kind="output" path="bin"/> | |||||
</classpath> |
<?xml version="1.0" encoding="UTF-8"?> | |||||
<projectDescription> | |||||
<name>weaver5</name> | |||||
<comment></comment> | |||||
<projects> | |||||
</projects> | |||||
<buildSpec> | |||||
<buildCommand> | |||||
<name>org.eclipse.jdt.core.javabuilder</name> | |||||
<arguments> | |||||
</arguments> | |||||
</buildCommand> | |||||
</buildSpec> | |||||
<natures> | |||||
<nature>org.eclipse.jdt.core.javanature</nature> | |||||
</natures> | |||||
</projectDescription> |
#Mon Sep 26 14:56:38 BST 2005 | |||||
eclipse.preferences.version=1 | |||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled | |||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 | |||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve | |||||
org.eclipse.jdt.core.compiler.compliance=1.5 | |||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate | |||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate | |||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate | |||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error | |||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error | |||||
org.eclipse.jdt.core.compiler.source=1.5 |
#Mon Sep 26 14:56:47 BST 2005 | |||||
eclipse.preferences.version=1 | |||||
internal.default.compliance=default |
<?xml version="1.0"?> | |||||
<!-- see ../build/*.html for explanation --> | |||||
<project name="weaver5" default="test" basedir="."> | |||||
<import file="${basedir}/../build/build.xml"/> | |||||
</project> | |||||
/* ******************************************************************* | |||||
* 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.reflect; | |||||
import java.lang.annotation.Annotation; | |||||
import java.lang.reflect.AccessibleObject; | |||||
import java.lang.reflect.Constructor; | |||||
import java.lang.reflect.Field; | |||||
import java.lang.reflect.Member; | |||||
import java.lang.reflect.Method; | |||||
import java.util.Collections; | |||||
import java.util.HashSet; | |||||
import java.util.Set; | |||||
import org.aspectj.apache.bcel.classfile.JavaClass; | |||||
import org.aspectj.apache.bcel.util.Repository; | |||||
import org.aspectj.apache.bcel.util.ClassLoaderRepository; | |||||
import org.aspectj.weaver.ResolvedType; | |||||
import org.aspectj.weaver.UnresolvedType; | |||||
import org.aspectj.weaver.World; | |||||
/** | |||||
* Find the given annotation (if present) on the given object | |||||
* | |||||
*/ | |||||
public class Java15AnnotationFinder implements AnnotationFinder { | |||||
private Repository bcelRepository; | |||||
public Java15AnnotationFinder() { | |||||
this.bcelRepository = new ClassLoaderRepository(getClass().getClassLoader()); | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.aspectj.weaver.reflect.AnnotationFinder#getAnnotation(org.aspectj.weaver.ResolvedType, java.lang.Object) | |||||
*/ | |||||
public Object getAnnotation(ResolvedType annotationType, Object onObject) { | |||||
try { | |||||
Class annotationClass = Class.forName(annotationType.getName()); | |||||
if (onObject.getClass().isAnnotationPresent(annotationClass)) { | |||||
return onObject.getClass().getAnnotation(annotationClass); | |||||
} | |||||
} catch (ClassNotFoundException ex) { | |||||
// just return null | |||||
} | |||||
return null; | |||||
} | |||||
public Object getAnnotationFromClass(ResolvedType annotationType, Class aClass) { | |||||
try { | |||||
Class annotationClass = Class.forName(annotationType.getName()); | |||||
if (aClass.isAnnotationPresent(annotationClass)) { | |||||
return aClass.getAnnotation(annotationClass); | |||||
} | |||||
} catch (ClassNotFoundException ex) { | |||||
// just return null | |||||
} | |||||
return null; | |||||
} | |||||
public Object getAnnotationFromMember(ResolvedType annotationType, Member aMember) { | |||||
if (!(aMember instanceof AccessibleObject)) return null; | |||||
AccessibleObject ao = (AccessibleObject) aMember; | |||||
try { | |||||
Class annotationClass = Class.forName(annotationType.getName()); | |||||
if (ao.isAnnotationPresent(annotationClass)) { | |||||
return ao.getAnnotation(annotationClass); | |||||
} | |||||
} catch (ClassNotFoundException ex) { | |||||
// just return null | |||||
} | |||||
return null; | |||||
} | |||||
public Set getAnnotations(Member onMember) { | |||||
if (!(onMember instanceof AccessibleObject)) return Collections.EMPTY_SET; | |||||
// here we really want both the runtime visible AND the class visible annotations | |||||
// so we bail out to Bcel and then chuck away the JavaClass so that we don't hog | |||||
// memory. | |||||
try { | |||||
JavaClass jc = bcelRepository.loadClass(onMember.getDeclaringClass()); | |||||
org.aspectj.apache.bcel.classfile.annotation.Annotation[] anns = new org.aspectj.apache.bcel.classfile.annotation.Annotation[0]; | |||||
if (onMember instanceof Method) { | |||||
org.aspectj.apache.bcel.classfile.Method bcelMethod = jc.getMethod((Method)onMember); | |||||
anns = bcelMethod.getAnnotations(); | |||||
} else if (onMember instanceof Constructor) { | |||||
org.aspectj.apache.bcel.classfile.Method bcelCons = jc.getMethod((Constructor)onMember); | |||||
anns = bcelCons.getAnnotations(); | |||||
} else if (onMember instanceof Field) { | |||||
org.aspectj.apache.bcel.classfile.Field bcelField = jc.getField((Field)onMember); | |||||
anns = bcelField.getAnnotations(); | |||||
} | |||||
// the answer is cached and we don't want to hold on to memory | |||||
bcelRepository.clear(); | |||||
if (anns == null) anns = new org.aspectj.apache.bcel.classfile.annotation.Annotation[0]; | |||||
// convert to our Annotation type | |||||
Set<UnresolvedType> annSet = new HashSet<UnresolvedType>(); | |||||
for (int i = 0; i < anns.length; i++) { | |||||
annSet.add(UnresolvedType.forName(anns[i].getTypeName())); | |||||
} | |||||
return annSet; | |||||
} catch (ClassNotFoundException cnfEx) { | |||||
// just use reflection then | |||||
} | |||||
AccessibleObject ao = (AccessibleObject) onMember; | |||||
Annotation[] anns = ao.getDeclaredAnnotations(); | |||||
Set<UnresolvedType> annSet = new HashSet<UnresolvedType>(); | |||||
for (int i = 0; i < anns.length; i++) { | |||||
annSet.add(UnresolvedType.forName(anns[i].annotationType().getName())); | |||||
} | |||||
return annSet; | |||||
} | |||||
public ResolvedType[] getAnnotations(Class forClass, World inWorld) { | |||||
// here we really want both the runtime visible AND the class visible annotations | |||||
// so we bail out to Bcel and then chuck away the JavaClass so that we don't hog | |||||
// memory. | |||||
try { | |||||
JavaClass jc = bcelRepository.loadClass(forClass); | |||||
org.aspectj.apache.bcel.classfile.annotation.Annotation[] anns =jc.getAnnotations(); | |||||
bcelRepository.clear(); | |||||
if (anns == null) return new ResolvedType[0]; | |||||
ResolvedType[] ret = new ResolvedType[anns.length]; | |||||
for (int i = 0; i < ret.length; i++) { | |||||
ret[i] = inWorld.resolve(anns[i].getTypeName()); | |||||
} | |||||
return ret; | |||||
} catch (ClassNotFoundException cnfEx) { | |||||
// just use reflection then | |||||
} | |||||
Annotation[] classAnnotations = forClass.getAnnotations(); | |||||
ResolvedType[] ret = new ResolvedType[classAnnotations.length]; | |||||
for (int i = 0; i < classAnnotations.length; i++) { | |||||
ret[i] = inWorld.resolve(classAnnotations[i].annotationType().getName()); | |||||
} | |||||
return ret; | |||||
} | |||||
} |
/* ******************************************************************* | |||||
* 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.reflect; | |||||
import java.lang.annotation.Retention; | |||||
import java.lang.annotation.RetentionPolicy; | |||||
import java.lang.reflect.Constructor; | |||||
import java.lang.reflect.Field; | |||||
import java.lang.reflect.GenericArrayType; | |||||
import java.lang.reflect.Method; | |||||
import java.lang.reflect.ParameterizedType; | |||||
import java.lang.reflect.Type; | |||||
import java.lang.reflect.WildcardType; | |||||
import org.aspectj.lang.annotation.Aspect; | |||||
import org.aspectj.lang.reflect.AjType; | |||||
import org.aspectj.lang.reflect.AjTypeSystem; | |||||
import org.aspectj.lang.reflect.Pointcut; | |||||
import org.aspectj.weaver.AnnotationX; | |||||
import org.aspectj.weaver.BoundedReferenceType; | |||||
import org.aspectj.weaver.ReferenceType; | |||||
import org.aspectj.weaver.ResolvedMember; | |||||
import org.aspectj.weaver.ResolvedPointcutDefinition; | |||||
import org.aspectj.weaver.ResolvedType; | |||||
import org.aspectj.weaver.TypeFactory; | |||||
import org.aspectj.weaver.TypeVariable; | |||||
import org.aspectj.weaver.TypeVariableReferenceType; | |||||
import org.aspectj.weaver.UnresolvedType; | |||||
import org.aspectj.weaver.World; | |||||
import org.aspectj.weaver.internal.tools.PointcutExpressionImpl; | |||||
import org.aspectj.weaver.tools.PointcutParameter; | |||||
import org.aspectj.weaver.tools.PointcutParser; | |||||
/** | |||||
* @author colyer | |||||
* Provides Java 5 behaviour in reflection based delegates (overriding | |||||
* 1.4 behaviour from superclass where appropriate) | |||||
*/ | |||||
public class Java15ReflectionBasedReferenceTypeDelegate extends | |||||
ReflectionBasedReferenceTypeDelegate { | |||||
private AjType myType; | |||||
private ResolvedType[] annotations; | |||||
private ResolvedMember[] pointcuts; | |||||
private ResolvedMember[] methods; | |||||
private ResolvedMember[] fields; | |||||
private TypeVariable[] typeVariables; | |||||
private ResolvedType superclass; | |||||
private ResolvedType[] superInterfaces; | |||||
private String genericSignature = null; | |||||
private Java15AnnotationFinder annotationFinder = new Java15AnnotationFinder(); | |||||
public Java15ReflectionBasedReferenceTypeDelegate() {} | |||||
public void initialize(ReferenceType aType, Class aClass, World aWorld) { | |||||
super.initialize(aType, aClass, aWorld); | |||||
myType = AjTypeSystem.getAjType(aClass); | |||||
} | |||||
public ReferenceType buildGenericType() { | |||||
return (ReferenceType) UnresolvedType.forGenericTypeVariables( | |||||
getResolvedTypeX().getSignature(), | |||||
getTypeVariables()).resolve(getWorld()); | |||||
} | |||||
public AnnotationX[] getAnnotations() { | |||||
// AMC - we seem not to need to implement this method... | |||||
throw new UnsupportedOperationException("getAnnotations on Java15ReflectionBasedReferenceTypeDelegate is not implemented yet"); | |||||
//return super.getAnnotations(); | |||||
} | |||||
public ResolvedType[] getAnnotationTypes() { | |||||
if (annotations == null) { | |||||
annotations = annotationFinder.getAnnotations(getBaseClass(), getWorld()); | |||||
} | |||||
return annotations; | |||||
} | |||||
public boolean hasAnnotation(UnresolvedType ofType) { | |||||
ResolvedType[] myAnns = getAnnotationTypes(); | |||||
ResolvedType toLookFor = ofType.resolve(getWorld()); | |||||
for (int i = 0; i < myAnns.length; i++) { | |||||
if (myAnns[i] == toLookFor) return true; | |||||
} | |||||
return false; | |||||
} | |||||
// use the MAP to ensure that any aj-synthetic fields are filtered out | |||||
public ResolvedMember[] getDeclaredFields() { | |||||
if (fields == null) { | |||||
Field[] reflectFields = this.myType.getDeclaredFields(); | |||||
this.fields = new ResolvedMember[reflectFields.length]; | |||||
for (int i = 0; i < reflectFields.length; i++) { | |||||
this.fields[i] = createGenericFieldMember(reflectFields[i]); | |||||
} | |||||
} | |||||
return fields; | |||||
} | |||||
public String getDeclaredGenericSignature() { | |||||
if (this.genericSignature == null && isGeneric()) { | |||||
} | |||||
return genericSignature; | |||||
} | |||||
public ResolvedType[] getDeclaredInterfaces() { | |||||
if (superInterfaces == null) { | |||||
Type[] genericInterfaces = getBaseClass().getGenericInterfaces(); | |||||
this.superInterfaces = fromTypes(genericInterfaces); | |||||
} | |||||
return superInterfaces; | |||||
} | |||||
public ResolvedType getSuperclass() { | |||||
if (superclass == null) | |||||
superclass = fromType(this.getBaseClass().getGenericSuperclass()); | |||||
return superclass; | |||||
} | |||||
public TypeVariable[] getTypeVariables() { | |||||
if (this.typeVariables == null) { | |||||
java.lang.reflect.TypeVariable[] tVars = this.getBaseClass().getTypeParameters(); | |||||
this.typeVariables = new TypeVariable[tVars.length]; | |||||
for (int i = 0; i < tVars.length; i++) { | |||||
this.typeVariables[i] = ((TypeVariableReferenceType) fromType(tVars[i])).getTypeVariable(); | |||||
} | |||||
} | |||||
return this.typeVariables; | |||||
} | |||||
// overrides super method since by using the MAP we can filter out advice | |||||
// methods that really shouldn't be seen in this list | |||||
public ResolvedMember[] getDeclaredMethods() { | |||||
if (methods == null) { | |||||
Method[] reflectMethods = this.myType.getDeclaredMethods(); | |||||
Constructor[] reflectCons = this.myType.getDeclaredConstructors(); | |||||
this.methods = new ResolvedMember[reflectMethods.length + reflectCons.length]; | |||||
for (int i = 0; i < reflectMethods.length; i++) { | |||||
this.methods[i] = createGenericMethodMember(reflectMethods[i]); | |||||
} | |||||
for (int i = 0; i < reflectCons.length; i++) { | |||||
this.methods[i + reflectMethods.length] = | |||||
createGenericConstructorMember(reflectCons[i]); | |||||
} | |||||
} | |||||
return methods; | |||||
} | |||||
private ResolvedMember createGenericMethodMember(Method forMethod) { | |||||
ReflectionBasedResolvedMemberImpl ret = | |||||
new ReflectionBasedResolvedMemberImpl(org.aspectj.weaver.Member.METHOD, | |||||
getResolvedTypeX(), | |||||
forMethod.getModifiers(), | |||||
fromType(forMethod.getGenericReturnType()), | |||||
forMethod.getName(), | |||||
fromTypes(forMethod.getGenericParameterTypes()), | |||||
fromTypes(forMethod.getGenericExceptionTypes()), | |||||
forMethod | |||||
); | |||||
return ret; | |||||
} | |||||
private ResolvedMember createGenericConstructorMember(Constructor forConstructor) { | |||||
ReflectionBasedResolvedMemberImpl ret = | |||||
new ReflectionBasedResolvedMemberImpl(org.aspectj.weaver.Member.METHOD, | |||||
getResolvedTypeX(), | |||||
forConstructor.getModifiers(), | |||||
getResolvedTypeX(), | |||||
"init", | |||||
fromTypes(forConstructor.getGenericParameterTypes()), | |||||
fromTypes(forConstructor.getGenericExceptionTypes()), | |||||
forConstructor | |||||
); | |||||
return ret; | |||||
} | |||||
private ResolvedMember createGenericFieldMember(Field forField) { | |||||
return new ReflectionBasedResolvedMemberImpl( | |||||
org.aspectj.weaver.Member.FIELD, | |||||
getResolvedTypeX(), | |||||
forField.getModifiers(), | |||||
fromType(forField.getGenericType()), | |||||
forField.getName(), | |||||
new UnresolvedType[0], | |||||
forField); | |||||
} | |||||
public ResolvedMember[] getDeclaredPointcuts() { | |||||
if (pointcuts == null) { | |||||
Pointcut[] pcs = this.myType.getDeclaredPointcuts(); | |||||
pointcuts = new ResolvedMember[pcs.length]; | |||||
PointcutParser parser = new PointcutParser(); | |||||
for (int i = 0; i < pcs.length; i++) { | |||||
Class[] ptypes = pcs[i].getParameterTypes(); | |||||
String[] pnames = pcs[i].getParameterNames(); | |||||
if (pnames.length != ptypes.length) { | |||||
throw new IllegalStateException("Required parameter names not available when parsing pointcut " + pcs[i].getName() + " in type " + getResolvedTypeX().getName()); | |||||
} | |||||
PointcutParameter[] parameters = new PointcutParameter[ptypes.length]; | |||||
for (int j = 0; j < parameters.length; j++) { | |||||
parameters[j] = parser.createPointcutParameter(pnames[j],ptypes[j]); | |||||
} | |||||
String pcExpr = pcs[i].getPointcutExpression().toString(); | |||||
PointcutExpressionImpl pEx = (PointcutExpressionImpl) parser.parsePointcutExpression(pcExpr,getBaseClass(),parameters); | |||||
org.aspectj.weaver.patterns.Pointcut pc = pEx.getUnderlyingPointcut(); | |||||
UnresolvedType[] weaverPTypes = new UnresolvedType[ptypes.length]; | |||||
for (int j = 0; j < weaverPTypes.length; j++) { | |||||
weaverPTypes[j] = UnresolvedType.forName(ptypes[j].getName()); | |||||
} | |||||
pointcuts[i] = new ResolvedPointcutDefinition(getResolvedTypeX(),pcs[i].getModifiers(),pcs[i].getName(),weaverPTypes,pc); | |||||
} | |||||
} | |||||
return pointcuts; | |||||
} | |||||
public boolean isAnnotation() { | |||||
return getBaseClass().isAnnotation(); | |||||
} | |||||
public boolean isAnnotationStyleAspect() { | |||||
return getBaseClass().isAnnotationPresent(Aspect.class); | |||||
} | |||||
public boolean isAnnotationWithRuntimeRetention() { | |||||
if (!isAnnotation()) return false; | |||||
if (getBaseClass().isAnnotationPresent(Retention.class)) { | |||||
Retention retention = (Retention) getBaseClass().getAnnotation(Retention.class); | |||||
RetentionPolicy policy = retention.value(); | |||||
return policy == RetentionPolicy.RUNTIME; | |||||
} else { | |||||
return false; | |||||
} | |||||
} | |||||
public boolean isAspect() { | |||||
return this.myType.isAspect(); | |||||
} | |||||
public boolean isEnum() { | |||||
return getBaseClass().isEnum(); | |||||
} | |||||
public boolean isGeneric() { | |||||
//return false; // for now | |||||
return getBaseClass().getTypeParameters().length > 0; | |||||
} | |||||
private ResolvedType fromType(Type aType) { | |||||
if (aType instanceof Class) { | |||||
return getWorld().resolve(((Class)aType).getName()); | |||||
} else if (aType instanceof ParameterizedType) { | |||||
ParameterizedType pt = (ParameterizedType) aType; | |||||
ResolvedType baseType = fromType(pt.getRawType()); | |||||
Type[] args = pt.getActualTypeArguments(); | |||||
ResolvedType[] resolvedArgs = fromTypes(args); | |||||
return TypeFactory.createParameterizedType(baseType, resolvedArgs, getWorld()); | |||||
} else if (aType instanceof java.lang.reflect.TypeVariable) { | |||||
java.lang.reflect.TypeVariable tv = (java.lang.reflect.TypeVariable) aType; | |||||
Type[] bounds = tv.getBounds(); | |||||
ResolvedType[] resBounds = fromTypes(bounds); | |||||
ResolvedType upperBound = resBounds[0]; | |||||
ResolvedType[] additionalBounds = new ResolvedType[0]; | |||||
if (resBounds.length > 1) { | |||||
additionalBounds = new ResolvedType[resBounds.length - 1]; | |||||
System.arraycopy(resBounds,1,additionalBounds,0,additionalBounds.length); | |||||
} | |||||
TypeVariable rt_tv = new TypeVariable(tv.getName(),upperBound,additionalBounds); | |||||
return new TypeVariableReferenceType(rt_tv,getWorld()); | |||||
} else if (aType instanceof WildcardType) { | |||||
WildcardType wildType = (WildcardType) aType; | |||||
Type[] lowerBounds = wildType.getLowerBounds(); | |||||
Type[] upperBounds = wildType.getUpperBounds(); | |||||
ResolvedType bound = null; | |||||
boolean isExtends = lowerBounds.length == 0; | |||||
if (isExtends) { | |||||
bound = fromType(upperBounds[0]); | |||||
} else { | |||||
bound = fromType(lowerBounds[0]); | |||||
} | |||||
return new BoundedReferenceType((ReferenceType)bound,isExtends,getWorld()); | |||||
} else if (aType instanceof GenericArrayType) { | |||||
GenericArrayType gt = (GenericArrayType) aType; | |||||
Type componentType = gt.getGenericComponentType(); | |||||
UnresolvedType.makeArray(fromType(componentType),1); | |||||
} | |||||
return ResolvedType.MISSING; | |||||
} | |||||
private ResolvedType[] fromTypes(Type[] types) { | |||||
ResolvedType[] ret = new ResolvedType[types.length]; | |||||
for (int i = 0; i < ret.length; i++) { | |||||
ret[i] = fromType(types[i]); | |||||
} | |||||
return ret; | |||||
} | |||||
} | |||||
/******************************************************************************* | |||||
* 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: (See CVS logs) | |||||
* | |||||
*******************************************************************************/ | |||||
import org.aspectj.testing.util.TestUtil; | |||||
import org.aspectj.util.LangUtil; | |||||
import junit.framework.Test; | |||||
import junit.framework.TestCase; | |||||
import junit.framework.TestSuite; | |||||
/** | |||||
*/ | |||||
public class Weaver5ModuleTests extends TestCase { | |||||
public static Test suite() { | |||||
TestSuite suite = new TestSuite(Weaver5ModuleTests.class.getName()); | |||||
if (TestUtil.is15VMOrGreater()) { | |||||
// if (LangUtil.is15VMOrGreater()) { | |||||
TestUtil.loadTestsReflectively(suite, "org.aspectj.weaver.tools.Java15PointcutExpressionTest", false); | |||||
// } | |||||
// TestUtil.loadTestsReflectively(suite, "Weaver515ModuleTests", true); | |||||
} else { | |||||
suite.addTest(TestUtil.testNamed("all tests require 1.5")); | |||||
} | |||||
return suite; | |||||
} | |||||
public static void main(String[] args) { | |||||
junit.textui.TestRunner.main(new String[] {Weaver5ModuleTests.class.getName()}); | |||||
} | |||||
} |
/* ******************************************************************* | |||||
* 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.lang.annotation.Retention; | |||||
import java.lang.annotation.RetentionPolicy; | |||||
import java.lang.reflect.Method; | |||||
import org.aspectj.lang.annotation.Pointcut; | |||||
import junit.framework.Test; | |||||
import junit.framework.TestCase; | |||||
import junit.framework.TestSuite; | |||||
/** | |||||
* @author colyer | |||||
* | |||||
*/ | |||||
public class Java15PointcutExpressionTest extends TestCase { | |||||
public static Test suite() { | |||||
TestSuite suite = new TestSuite("Java15PointcutExpressionTest"); | |||||
suite.addTestSuite(Java15PointcutExpressionTest.class); | |||||
return suite; | |||||
} | |||||
private PointcutParser parser; | |||||
private Method a; | |||||
private Method b; | |||||
private Method c; | |||||
public void testAtThis() { | |||||
PointcutExpression atThis = parser.parsePointcutExpression("@this(org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)"); | |||||
ShadowMatch sMatch1 = atThis.matchesMethodExecution(a); | |||||
ShadowMatch sMatch2 = atThis.matchesMethodExecution(b); | |||||
assertTrue("maybe matches A",sMatch1.maybeMatches()); | |||||
assertTrue("maybe matches B",sMatch2.maybeMatches()); | |||||
JoinPointMatch jp1 = sMatch1.matchesJoinPoint(new A(), new A(), new Object[0]); | |||||
assertFalse("does not match",jp1.matches()); | |||||
JoinPointMatch jp2 = sMatch2.matchesJoinPoint(new B(), new B(), new Object[0]); | |||||
assertTrue("matches",jp2.matches()); | |||||
} | |||||
public void testAtTarget() { | |||||
PointcutExpression atTarget = parser.parsePointcutExpression("@target(org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)"); | |||||
ShadowMatch sMatch1 = atTarget.matchesMethodExecution(a); | |||||
ShadowMatch sMatch2 = atTarget.matchesMethodExecution(b); | |||||
assertTrue("maybe matches A",sMatch1.maybeMatches()); | |||||
assertTrue("maybe matches B",sMatch2.maybeMatches()); | |||||
JoinPointMatch jp1 = sMatch1.matchesJoinPoint(new A(), new A(), new Object[0]); | |||||
assertFalse("does not match",jp1.matches()); | |||||
JoinPointMatch jp2 = sMatch2.matchesJoinPoint(new B(), new B(), new Object[0]); | |||||
assertTrue("matches",jp2.matches()); | |||||
} | |||||
public void testAtThisWithBinding() { | |||||
PointcutParameter param = parser.createPointcutParameter("a",MyAnnotation.class); | |||||
B myB = new B(); | |||||
MyAnnotation bAnnotation = B.class.getAnnotation(MyAnnotation.class); | |||||
PointcutExpression atThis = parser.parsePointcutExpression("@this(a)",A.class,new PointcutParameter[] {param}); | |||||
ShadowMatch sMatch1 = atThis.matchesMethodExecution(a); | |||||
ShadowMatch sMatch2 = atThis.matchesMethodExecution(b); | |||||
assertTrue("maybe matches A",sMatch1.maybeMatches()); | |||||
assertTrue("maybe matches B",sMatch2.maybeMatches()); | |||||
JoinPointMatch jp1 = sMatch1.matchesJoinPoint(new A(), new A(), new Object[0]); | |||||
assertFalse("does not match",jp1.matches()); | |||||
JoinPointMatch jp2 = sMatch2.matchesJoinPoint(myB, myB, new Object[0]); | |||||
assertTrue("matches",jp2.matches()); | |||||
assertEquals(1,jp2.getParameterBindings().length); | |||||
assertEquals("should be myB's annotation",bAnnotation,jp2.getParameterBindings()[0].getBinding()); | |||||
} | |||||
public void testAtTargetWithBinding() { | |||||
PointcutParameter param = parser.createPointcutParameter("a",MyAnnotation.class); | |||||
B myB = new B(); | |||||
MyAnnotation bAnnotation = B.class.getAnnotation(MyAnnotation.class); | |||||
PointcutExpression atThis = parser.parsePointcutExpression("@target(a)",A.class,new PointcutParameter[] {param}); | |||||
ShadowMatch sMatch1 = atThis.matchesMethodExecution(a); | |||||
ShadowMatch sMatch2 = atThis.matchesMethodExecution(b); | |||||
assertTrue("maybe matches A",sMatch1.maybeMatches()); | |||||
assertTrue("maybe matches B",sMatch2.maybeMatches()); | |||||
JoinPointMatch jp1 = sMatch1.matchesJoinPoint(new A(), new A(), new Object[0]); | |||||
assertFalse("does not match",jp1.matches()); | |||||
JoinPointMatch jp2 = sMatch2.matchesJoinPoint(myB, myB, new Object[0]); | |||||
assertTrue("matches",jp2.matches()); | |||||
assertEquals(1,jp2.getParameterBindings().length); | |||||
assertEquals("should be myB's annotation",bAnnotation,jp2.getParameterBindings()[0].getBinding()); | |||||
} | |||||
public void testAtArgs() { | |||||
PointcutExpression atArgs = parser.parsePointcutExpression("@args(..,org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)"); | |||||
ShadowMatch sMatch1 = atArgs.matchesMethodExecution(a); | |||||
ShadowMatch sMatch2 = atArgs.matchesMethodExecution(c); | |||||
assertTrue("never matches A",sMatch1.neverMatches()); | |||||
assertTrue("maybe matches C",sMatch2.maybeMatches()); | |||||
JoinPointMatch jp2 = sMatch2.matchesJoinPoint(new B(), new B(), new Object[]{new A(),new B()}); | |||||
assertTrue("matches",jp2.matches()); | |||||
atArgs = parser.parsePointcutExpression("@args(org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation,org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)"); | |||||
sMatch1 = atArgs.matchesMethodExecution(a); | |||||
sMatch2 = atArgs.matchesMethodExecution(c); | |||||
assertTrue("never matches A",sMatch1.neverMatches()); | |||||
assertTrue("maybe matches C",sMatch2.maybeMatches()); | |||||
JoinPointMatch jp1 = sMatch2.matchesJoinPoint(new A(), new A(), new Object[] {new A(), new B()}); | |||||
assertFalse("does not match",jp1.matches()); | |||||
jp2 = sMatch2.matchesJoinPoint(new B(), new B(), new Object[] {new B(),new B()}); | |||||
assertTrue("matches",jp2.matches()); | |||||
} | |||||
public void testAtArgsWithBinding() { | |||||
PointcutParameter p1 = parser.createPointcutParameter("a",MyAnnotation.class); | |||||
PointcutParameter p2 = parser.createPointcutParameter("b", MyAnnotation.class); | |||||
PointcutExpression atArgs = parser.parsePointcutExpression("@args(..,a)",A.class,new PointcutParameter[] {p1}); | |||||
ShadowMatch sMatch2 = atArgs.matchesMethodExecution(c); | |||||
assertTrue("maybe matches C",sMatch2.maybeMatches()); | |||||
JoinPointMatch jp2 = sMatch2.matchesJoinPoint(new B(), new B(), new Object[]{new A(),new B()}); | |||||
assertTrue("matches",jp2.matches()); | |||||
assertEquals(1,jp2.getParameterBindings().length); | |||||
MyAnnotation bAnnotation = B.class.getAnnotation(MyAnnotation.class); | |||||
assertEquals("annotation on B",bAnnotation,jp2.getParameterBindings()[0].getBinding()); | |||||
atArgs = parser.parsePointcutExpression("@args(a,b)",A.class,new PointcutParameter[] {p1,p2}); | |||||
sMatch2 = atArgs.matchesMethodExecution(c); | |||||
assertTrue("maybe matches C",sMatch2.maybeMatches()); | |||||
jp2 = sMatch2.matchesJoinPoint(new B(), new B(), new Object[] {new B(),new B()}); | |||||
assertTrue("matches",jp2.matches()); | |||||
assertEquals(2,jp2.getParameterBindings().length); | |||||
assertEquals("annotation on B",bAnnotation,jp2.getParameterBindings()[0].getBinding()); | |||||
assertEquals("annotation on B",bAnnotation,jp2.getParameterBindings()[1].getBinding()); | |||||
} | |||||
public void testAtWithin() { | |||||
PointcutExpression atWithin = parser.parsePointcutExpression("@within(org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)"); | |||||
ShadowMatch sMatch1 = atWithin.matchesMethodExecution(a); | |||||
ShadowMatch sMatch2 = atWithin.matchesMethodExecution(b); | |||||
assertTrue("does not match a",sMatch1.neverMatches()); | |||||
assertTrue("matches b",sMatch2.alwaysMatches()); | |||||
} | |||||
public void testAtWithinWithBinding() { | |||||
PointcutParameter p1 = parser.createPointcutParameter("x",MyAnnotation.class); | |||||
PointcutExpression atWithin = parser.parsePointcutExpression("@within(x)",B.class,new PointcutParameter[] {p1}); | |||||
ShadowMatch sMatch1 = atWithin.matchesMethodExecution(a); | |||||
ShadowMatch sMatch2 = atWithin.matchesMethodExecution(b); | |||||
assertTrue("does not match a",sMatch1.neverMatches()); | |||||
assertTrue("matches b",sMatch2.alwaysMatches()); | |||||
JoinPointMatch jpm = sMatch2.matchesJoinPoint(new B(), new B(), new Object[0]); | |||||
assertTrue(jpm.matches()); | |||||
assertEquals(1,jpm.getParameterBindings().length); | |||||
MyAnnotation bAnnotation = B.class.getAnnotation(MyAnnotation.class); | |||||
assertEquals("annotation on B",bAnnotation,jpm.getParameterBindings()[0].getBinding()); | |||||
} | |||||
public void testAtWithinCode() { | |||||
PointcutExpression atWithinCode = parser.parsePointcutExpression("@withincode(org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)"); | |||||
ShadowMatch sMatch1 = atWithinCode.matchesMethodCall(a,b); | |||||
ShadowMatch sMatch2 = atWithinCode.matchesMethodCall(a,a); | |||||
assertTrue("does not match from b",sMatch1.neverMatches()); | |||||
assertTrue("matches from a",sMatch2.alwaysMatches()); | |||||
} | |||||
public void testAtWithinCodeWithBinding() { | |||||
PointcutParameter p1 = parser.createPointcutParameter("x",MyAnnotation.class); | |||||
PointcutExpression atWithinCode = parser.parsePointcutExpression("@withincode(x)",A.class,new PointcutParameter[] {p1}); | |||||
ShadowMatch sMatch2 = atWithinCode.matchesMethodCall(a,a); | |||||
assertTrue("matches from a",sMatch2.alwaysMatches()); | |||||
JoinPointMatch jpm = sMatch2.matchesJoinPoint(new A(), new A(), new Object[0]); | |||||
assertEquals(1,jpm.getParameterBindings().length); | |||||
MyAnnotation annOna = a.getAnnotation(MyAnnotation.class); | |||||
assertEquals("MyAnnotation on a",annOna,jpm.getParameterBindings()[0].getBinding()); | |||||
} | |||||
public void testAtAnnotation() { | |||||
PointcutExpression atAnnotation = parser.parsePointcutExpression("@annotation(org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)"); | |||||
ShadowMatch sMatch1 = atAnnotation.matchesMethodCall(b,a); | |||||
ShadowMatch sMatch2 = atAnnotation.matchesMethodCall(a,a); | |||||
assertTrue("does not match call to b",sMatch1.neverMatches()); | |||||
assertTrue("matches call to a",sMatch2.alwaysMatches()); | |||||
} | |||||
public void testAtAnnotationWithBinding() { | |||||
PointcutParameter p1 = parser.createPointcutParameter("x",MyAnnotation.class); | |||||
PointcutExpression atAnnotation = parser.parsePointcutExpression("@annotation(x)",A.class,new PointcutParameter[] {p1}); | |||||
ShadowMatch sMatch2 = atAnnotation.matchesMethodCall(a,a); | |||||
assertTrue("matches call to a",sMatch2.alwaysMatches()); | |||||
JoinPointMatch jpm = sMatch2.matchesJoinPoint(new A(), new A(), new Object[0]); | |||||
assertTrue(jpm.matches()); | |||||
assertEquals(1,jpm.getParameterBindings().length); | |||||
MyAnnotation annOna = a.getAnnotation(MyAnnotation.class); | |||||
assertEquals("MyAnnotation on a",annOna,jpm.getParameterBindings()[0].getBinding()); | |||||
} | |||||
public void testReferencePointcutNoParams() { | |||||
PointcutExpression pc = parser.parsePointcutExpression("foo()",C.class,new PointcutParameter[0]); | |||||
ShadowMatch sMatch1 = pc.matchesMethodCall(a,b); | |||||
ShadowMatch sMatch2 = pc.matchesMethodExecution(a); | |||||
assertTrue("no match on call",sMatch1.neverMatches()); | |||||
assertTrue("match on execution",sMatch2.alwaysMatches()); | |||||
pc = parser.parsePointcutExpression("org.aspectj.weaver.tools.Java15PointcutExpressionTest.C.foo()"); | |||||
sMatch1 = pc.matchesMethodCall(a,b); | |||||
sMatch2 = pc.matchesMethodExecution(a); | |||||
assertTrue("no match on call",sMatch1.neverMatches()); | |||||
assertTrue("match on execution",sMatch2.alwaysMatches()); | |||||
} | |||||
public void testReferencePointcutParams() { | |||||
PointcutParameter p1 = parser.createPointcutParameter("x",A.class); | |||||
PointcutExpression pc = parser.parsePointcutExpression("goo(x)",C.class,new PointcutParameter[] {p1}); | |||||
ShadowMatch sMatch1 = pc.matchesMethodCall(a,b); | |||||
ShadowMatch sMatch2 = pc.matchesMethodExecution(a); | |||||
assertTrue("no match on call",sMatch1.neverMatches()); | |||||
assertTrue("match on execution",sMatch2.maybeMatches()); | |||||
A anA = new A(); | |||||
JoinPointMatch jpm = sMatch2.matchesJoinPoint(anA, new A(), new Object[0]); | |||||
assertTrue(jpm.matches()); | |||||
assertEquals("should be bound to anA",anA,jpm.getParameterBindings()[0].getBinding()); | |||||
} | |||||
public void testExecutionWithClassFileRetentionAnnotation() { | |||||
PointcutExpression pc1 = parser.parsePointcutExpression("execution(@org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation * *(..))"); | |||||
PointcutExpression pc2 = parser.parsePointcutExpression("execution(@org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyClassFileRetentionAnnotation * *(..))"); | |||||
ShadowMatch sMatch = pc1.matchesMethodExecution(a); | |||||
assertTrue("matches",sMatch.alwaysMatches()); | |||||
sMatch = pc2.matchesMethodExecution(a); | |||||
assertTrue("no match",sMatch.neverMatches()); | |||||
sMatch = pc1.matchesMethodExecution(b); | |||||
assertTrue("no match",sMatch.neverMatches()); | |||||
sMatch = pc2.matchesMethodExecution(b); | |||||
assertTrue("matches",sMatch.alwaysMatches()); | |||||
} | |||||
protected void setUp() throws Exception { | |||||
super.setUp(); | |||||
parser = new PointcutParser(); | |||||
a = A.class.getMethod("a"); | |||||
b = B.class.getMethod("b"); | |||||
c = B.class.getMethod("c",new Class[] {A.class,B.class}); | |||||
} | |||||
@Retention(RetentionPolicy.RUNTIME) | |||||
private @interface MyAnnotation {} | |||||
private @interface MyClassFileRetentionAnnotation {} | |||||
private static class A { | |||||
@MyAnnotation public void a() {} | |||||
} | |||||
@MyAnnotation | |||||
private static class B { | |||||
@MyClassFileRetentionAnnotation public void b() {} | |||||
public void c(A anA, B aB) {} | |||||
} | |||||
private static class C { | |||||
@Pointcut("execution(* *(..))") | |||||
public void foo() {} | |||||
@Pointcut(value="execution(* *(..)) && this(x)", argNames="x") | |||||
public void goo(A x) {} | |||||
} | |||||
} | |||||