diff options
author | acolyer <acolyer> | 2005-04-25 16:04:10 +0000 |
---|---|---|
committer | acolyer <acolyer> | 2005-04-25 16:04:10 +0000 |
commit | 92fce1440c9017376efaf544802d8cef07546b03 (patch) | |
tree | 35640fd1a53ce26bb0097e33a9f5fdd0bd8b4e20 | |
parent | 1ff2a95b303cd615d5b689b1bdf79a7f201c62a3 (diff) | |
download | aspectj-92fce1440c9017376efaf544802d8cef07546b03.tar.gz aspectj-92fce1440c9017376efaf544802d8cef07546b03.zip |
this patch implements the MAP for aspects, pointcuts, and advice. just enough of an implementation to provide the support needed for some of the ataspectj visitor tests.
18 files changed, 1290 insertions, 54 deletions
diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/annotation/ajcPrivileged.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/annotation/ajcPrivileged.java new file mode 100644 index 000000000..78ca43e05 --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/annotation/ajcPrivileged.java @@ -0,0 +1,27 @@ +/* ******************************************************************* + * 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.internal.lang.annotation; + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + + +/** + * @author colyer + * Marker annotation for privileged aspects. + * ajc prefix used to indicate that this annotation is *internal* + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface ajcPrivileged {} diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/AdviceImpl.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/AdviceImpl.java new file mode 100644 index 000000000..f29d93599 --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/AdviceImpl.java @@ -0,0 +1,55 @@ +/* ******************************************************************* + * 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.internal.lang.reflect; + +import java.lang.reflect.Method; + +import org.aspectj.lang.annotation.AdviceName; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.reflect.Advice; +import org.aspectj.lang.reflect.AdviceType; + +/** + * @author colyer + * + */ +public class AdviceImpl implements Advice { + + private final AdviceType kind; + private final Method adviceMethod; + private String pointcutExpression; + + protected AdviceImpl(Method method, String pointcut, AdviceType type) { + this.kind = type; + this.adviceMethod = method; + this.pointcutExpression = pointcut; + } + + public AdviceType getKind() { + return kind; + } + + public String getName() { + String adviceName = adviceMethod.getName(); + if (adviceName.startsWith("ajc$")) { + adviceName = ""; + AdviceName name = adviceMethod.getAnnotation(AdviceName.class); + if (name != null) adviceName = name.value(); + } + return adviceName; + } + + public String getPointcutExpression() { + return pointcutExpression; + } + +} diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/AjTypeImpl.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/AjTypeImpl.java index 4fc4ab5a7..09db33898 100644 --- a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/AjTypeImpl.java +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/AjTypeImpl.java @@ -17,10 +17,23 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; - +import java.util.ArrayList; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.List; +import java.util.Set; + +import org.aspectj.internal.lang.annotation.ajcPrivileged; +import org.aspectj.lang.annotation.After; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; import org.aspectj.lang.reflect.Advice; import org.aspectj.lang.reflect.AdviceType; import org.aspectj.lang.reflect.AjType; +import org.aspectj.lang.reflect.AjTypeSystem; import org.aspectj.lang.reflect.DeclareAnnotation; import org.aspectj.lang.reflect.DeclareErrorOrWarning; import org.aspectj.lang.reflect.DeclareParents; @@ -29,16 +42,26 @@ import org.aspectj.lang.reflect.DeclareSoft; import org.aspectj.lang.reflect.InterTypeConstructorDeclaration; import org.aspectj.lang.reflect.InterTypeFieldDeclaration; import org.aspectj.lang.reflect.InterTypeMethodDeclaration; +import org.aspectj.lang.reflect.NoSuchAdviceException; +import org.aspectj.lang.reflect.NoSuchPointcutException; import org.aspectj.lang.reflect.PerClause; +import org.aspectj.lang.reflect.PerClauseKind; import org.aspectj.lang.reflect.Pointcut; + /** * @author colyer * */ public class AjTypeImpl<T> implements AjType { + private static final String ajcMagic = "ajc$"; + private Class<T> clazz; + private Pointcut[] declaredPointcuts = null; + private Pointcut[] pointcuts = null; + private Advice[] declaredAdvice = null; + private Advice[] advice = null; public AjTypeImpl(Class<T> fromClass) { this.clazz = fromClass; @@ -117,7 +140,27 @@ public class AjTypeImpl<T> implements AjType { } public PerClause getPerClause() { - return null; + if (isAspect()) { + Aspect aspectAnn = clazz.getAnnotation(Aspect.class); + String perClause = aspectAnn.value(); + if (perClause.equals("")) { + return new PerClauseImpl(PerClauseKind.SINGLETON,""); + } else if (perClause.startsWith("perthis(")) { + return new PerClauseImpl(PerClauseKind.PERTHIS,perClause.substring("perthis(".length(),perClause.length() - 1)); + } else if (perClause.startsWith("pertarget(")) { + return new PerClauseImpl(PerClauseKind.PERTARGET,perClause.substring("pertarget(".length(),perClause.length() - 1)); + } else if (perClause.startsWith("percflow(")) { + return new PerClauseImpl(PerClauseKind.PERCFLOW,perClause.substring("percflow(".length(),perClause.length() - 1)); + } else if (perClause.startsWith("percflowbelow(")) { + return new PerClauseImpl(PerClauseKind.PERCFLOWBELOW,perClause.substring("percflowbelow(".length(),perClause.length() - 1)); + } else if (perClause.startsWith("pertypewithin")) { + return new PerClauseImpl(PerClauseKind.PERTYPEWITHIN,perClause.substring("pertypewithin(".length(),perClause.length() - 1)); + } else { + throw new IllegalStateException("Per-clause not recognized: " + perClause); + } + } else { + return null; + } } /* (non-Javadoc) @@ -201,106 +244,289 @@ public class AjTypeImpl<T> implements AjType { * @see org.aspectj.lang.reflect.AjType#getDeclaredField(java.lang.String) */ public Field getDeclaredField(String name) throws NoSuchFieldException { - return clazz.getDeclaredField(name); + Field f = clazz.getDeclaredField(name); + if (f.getName().startsWith(ajcMagic)) throw new NoSuchFieldException(name); + return f; } /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getDeclaredFields() */ public Field[] getDeclaredFields() { - return clazz.getDeclaredFields(); + Field[] fields = clazz.getDeclaredFields(); + List<Field> filteredFields = new ArrayList<Field>(); + for (Field field : fields) + if (!field.getName().startsWith(ajcMagic)) filteredFields.add(field); + Field[] ret = new Field[filteredFields.size()]; + filteredFields.toArray(ret); + return ret; } /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getField(java.lang.String) */ public Field getField(String name) throws NoSuchFieldException { - return clazz.getField(name); + Field f = clazz.getDeclaredField(name); + if (f.getName().startsWith(ajcMagic)) throw new NoSuchFieldException(name); + return f; } /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getFields() */ public Field[] getFields() { - return clazz.getFields(); + Field[] fields = clazz.getFields(); + List<Field> filteredFields = new ArrayList<Field>(); + for (Field field : fields) + if (!field.getName().startsWith(ajcMagic)) filteredFields.add(field); + Field[] ret = new Field[filteredFields.size()]; + filteredFields.toArray(ret); + return ret; } /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getDeclaredMethod(java.lang.String, java.lang.Class...) */ public Method getDeclaredMethod(String name, Class... parameterTypes) throws NoSuchMethodException { - return clazz.getDeclaredMethod(name,parameterTypes); + Method m = clazz.getDeclaredMethod(name,parameterTypes); + if (!isReallyAMethod(m)) throw new NoSuchMethodException(name); + return m; } /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getMethod(java.lang.String, java.lang.Class...) */ public Method getMethod(String name, Class... parameterTypes) throws NoSuchMethodException { - return clazz.getMethod(name,parameterTypes); + Method m = clazz.getMethod(name,parameterTypes); + if (!isReallyAMethod(m)) throw new NoSuchMethodException(name); + return m; } /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getDeclaredMethods() */ public Method[] getDeclaredMethods() { - return clazz.getDeclaredMethods(); + Method[] methods = clazz.getDeclaredMethods(); + List<Method> filteredMethods = new ArrayList<Method>(); + for (Method method : methods) { + if (isReallyAMethod(method)) filteredMethods.add(method); + } + Method[] ret = new Method[filteredMethods.size()]; + filteredMethods.toArray(ret); + return ret; } /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getMethods() */ public Method[] getMethods() { - return clazz.getMethods(); + Method[] methods = clazz.getMethods(); + List<Method> filteredMethods = new ArrayList<Method>(); + for (Method method : methods) { + if (isReallyAMethod(method)) filteredMethods.add(method); + } + Method[] ret = new Method[filteredMethods.size()]; + filteredMethods.toArray(ret); + return ret; } + private boolean isReallyAMethod(Method method) { + if (method.getName().startsWith(ajcMagic)) return false; + if (method.isAnnotationPresent(org.aspectj.lang.annotation.Pointcut.class)) return false; + if (method.isAnnotationPresent(Before.class)) return false; + if (method.isAnnotationPresent(After.class)) return false; + if (method.isAnnotationPresent(AfterReturning.class)) return false; + if (method.isAnnotationPresent(AfterThrowing.class)) return false; + if (method.isAnnotationPresent(Around.class)) return false; + return true; + } + /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getDeclaredPointcut(java.lang.String) */ - public Pointcut getDeclaredPointcut(String name) { - // TODO Auto-generated method stub - return null; + public Pointcut getDeclaredPointcut(String name) throws NoSuchPointcutException { + Pointcut[] pcs = getDeclaredPointcuts(); + for (Pointcut pc : pcs) + if (pc.getName().equals(name)) return pc; + throw new NoSuchPointcutException(name); } /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getPointcut(java.lang.String) */ - public Pointcut getPointcut(String name) { - // TODO Auto-generated method stub - return null; + public Pointcut getPointcut(String name) throws NoSuchPointcutException { + Pointcut[] pcs = getDeclaredPointcuts(); + for (Pointcut pc : pcs) + if (pc.getName().equals(name)) return pc; + throw new NoSuchPointcutException(name); } /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getDeclaredPointcuts() */ public Pointcut[] getDeclaredPointcuts() { - // TODO Auto-generated method stub - return null; + if (declaredPointcuts != null) return declaredPointcuts; + List<Pointcut> pointcuts = new ArrayList<Pointcut>(); + Method[] methods = clazz.getDeclaredMethods(); + for (Method method : methods) { + Pointcut pc = asPointcut(method); + if (pc != null) pointcuts.add(pc); + } + Pointcut[] ret = new Pointcut[pointcuts.size()]; + pointcuts.toArray(ret); + declaredPointcuts = ret; + return ret; } /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getPointcuts() */ public Pointcut[] getPointcuts() { - // TODO Auto-generated method stub - return null; + if (pointcuts != null) return pointcuts; + List<Pointcut> pcuts = new ArrayList<Pointcut>(); + Method[] methods = clazz.getMethods(); + for (Method method : methods) { + Pointcut pc = asPointcut(method); + if (pc != null) pcuts.add(pc); + } + Pointcut[] ret = new Pointcut[pcuts.size()]; + pcuts.toArray(ret); + pointcuts = ret; + return ret; + } + + private Pointcut asPointcut(Method method) { + org.aspectj.lang.annotation.Pointcut pcAnn = method.getAnnotation(org.aspectj.lang.annotation.Pointcut.class); + if (pcAnn != null) { + String name = method.getName(); + if (name.startsWith(ajcMagic)) { + // extract real name + int nameStart = name.indexOf("$$"); + name = name.substring(nameStart +2,name.length()); + int nextDollar = name.indexOf("$"); + if (nextDollar != -1) name = name.substring(0,nextDollar); + } + return new PointcutImpl(name,pcAnn.value(),method,AjTypeSystem.getAjType(method.getDeclaringClass())); + } else { + return null; + } + } + + + public Advice[] getDeclaredAdvice(AdviceType... ofType) { + Set<AdviceType> types; + if (ofType.length == 0) { + types = EnumSet.allOf(AdviceType.class); + } else { + types = EnumSet.noneOf(AdviceType.class); + types.addAll(Arrays.asList(ofType)); + } + return getDeclaredAdvice(types); + } + + public Advice[] getAdvice(AdviceType... ofType) { + Set<AdviceType> types; + if (ofType.length == 0) { + types = EnumSet.allOf(AdviceType.class); + } else { + types = EnumSet.noneOf(AdviceType.class); + types.addAll(Arrays.asList(ofType)); + } + return getAdvice(types); } /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getDeclaredAdvice(org.aspectj.lang.reflect.AdviceType) */ - public Advice[] getDeclaredAdvice(AdviceType adviceType) { - // TODO Auto-generated method stub - return null; + private Advice[] getDeclaredAdvice(Set ofAdviceTypes) { + if (declaredAdvice == null) initDeclaredAdvice(); + List<Advice> adviceList = new ArrayList<Advice>(); + for (Advice a : declaredAdvice) { + if (ofAdviceTypes.contains(a.getKind())) adviceList.add(a); + } + Advice[] ret = new Advice[adviceList.size()]; + adviceList.toArray(ret); + return ret; + } + + private void initDeclaredAdvice() { + Method[] methods = clazz.getDeclaredMethods(); + List<Advice> adviceList = new ArrayList<Advice>(); + for (Method method : methods) { + Advice advice = asAdvice(method); + if (advice != null) adviceList.add(advice); + } + declaredAdvice = new Advice[adviceList.size()]; + adviceList.toArray(declaredAdvice); } /* (non-Javadoc) - * @see org.aspectj.lang.reflect.AjType#getAdvice(org.aspectj.lang.reflect.AdviceType) + * @see org.aspectj.lang.reflect.AjType#getDeclaredAdvice(org.aspectj.lang.reflect.AdviceType) */ - public Advice[] getAdvice(AdviceType adviceType) { - // TODO Auto-generated method stub - return null; + private Advice[] getAdvice(Set ofAdviceTypes) { + if (advice == null) initAdvice(); + List<Advice> adviceList = new ArrayList<Advice>(); + for (Advice a : advice) { + if (ofAdviceTypes.contains(a.getKind())) adviceList.add(a); + } + Advice[] ret = new Advice[adviceList.size()]; + adviceList.toArray(ret); + return ret; } + private void initAdvice() { + Method[] methods = clazz.getDeclaredMethods(); + List<Advice> adviceList = new ArrayList<Advice>(); + for (Method method : methods) { + Advice advice = asAdvice(method); + if (advice != null) adviceList.add(advice); + } + advice = new Advice[adviceList.size()]; + adviceList.toArray(advice); + } + + + public Advice getAdvice(String name) throws NoSuchAdviceException { + if (name.equals("")) throw new IllegalArgumentException("use getAdvice(AdviceType...) instead for un-named advice"); + if (advice == null) initAdvice(); + for (Advice a : advice) { + if (a.getName().equals(name)) return a; + } + throw new NoSuchAdviceException(name); + } + + public Advice getDeclaredAdvice(String name) throws NoSuchAdviceException { + if (name.equals("")) throw new IllegalArgumentException("use getAdvice(AdviceType...) instead for un-named advice"); + if (declaredAdvice == null) initDeclaredAdvice(); + for (Advice a : declaredAdvice) { + if (a.getName().equals(name)) return a; + } + throw new NoSuchAdviceException(name); + } + + private Advice asAdvice(Method method) { + if (method.getAnnotations().length == 0) return null; + Before beforeAnn = method.getAnnotation(Before.class); + if (beforeAnn != null) return new AdviceImpl(method,beforeAnn.value(),AdviceType.BEFORE); + After afterAnn = method.getAnnotation(After.class); + if (afterAnn != null) return new AdviceImpl(method,afterAnn.value(),AdviceType.AFTER); + AfterReturning afterReturningAnn = method.getAnnotation(AfterReturning.class); + if (afterReturningAnn != null) { + String pcExpr = afterReturningAnn.pointcut(); + if (pcExpr.equals("")) pcExpr = afterReturningAnn.value(); + return new AdviceImpl(method,pcExpr,AdviceType.AFTER_RETURNING); + } + AfterThrowing afterThrowingAnn = method.getAnnotation(AfterThrowing.class); + if (afterThrowingAnn != null) { + String pcExpr = afterThrowingAnn.pointcut(); + if (pcExpr == null) pcExpr = afterThrowingAnn.value(); + return new AdviceImpl(method,pcExpr,AdviceType.AFTER_THROWING); + } + Around aroundAnn = method.getAnnotation(Around.class); + if (aroundAnn != null) return new AdviceImpl(method,aroundAnn.value(),AdviceType.AROUND); + return null; + } + /* (non-Javadoc) * @see org.aspectj.lang.reflect.AjType#getDeclaredITDMethod(java.lang.String, java.lang.Class, java.lang.Class...) */ @@ -509,12 +735,7 @@ public class AjTypeImpl<T> implements AjType { * @see org.aspectj.lang.reflect.AjType#isAspect() */ public boolean isAspect() { - // 2 tests we could use today... presence of aspectOf method (but what if user defines one in - // a class), and presence of @Aspect annotation (@AspectJ style only). - // Is the solution to put the @Aspect annotation on a code-style aspect too during weaving? - // Or should we generate some private structure with all the reflection info in it, including the aspect - // info? - return false; + return clazz.getAnnotation(Aspect.class) != null; } /* (non-Javadoc) @@ -524,4 +745,20 @@ public class AjTypeImpl<T> implements AjType { return clazz.isMemberClass() && isAspect(); } + public boolean isPrivileged() { + return isAspect() && clazz.isAnnotationPresent(ajcPrivileged.class); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof AjTypeImpl)) return false; + AjTypeImpl other = (AjTypeImpl) obj; + return other.clazz.equals(clazz); + } + + @Override + public int hashCode() { + return clazz.hashCode(); + } + } diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/PerClauseImpl.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/PerClauseImpl.java new file mode 100644 index 000000000..a589f79dc --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/PerClauseImpl.java @@ -0,0 +1,45 @@ +/* ******************************************************************* + * 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.internal.lang.reflect; + +import org.aspectj.lang.reflect.PerClause; +import org.aspectj.lang.reflect.PerClauseKind; + +/** + * @author colyer + * + */ +public class PerClauseImpl implements PerClause { + + private final PerClauseKind kind; + private final String pointcutExpression; + + protected PerClauseImpl(PerClauseKind kind, String pointcutExpression) { + this.kind = kind; + this.pointcutExpression = pointcutExpression; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.PerClause#getKind() + */ + public PerClauseKind getKind() { + return kind; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.PerClause#getPointcutExpression() + */ + public String getPointcutExpression() { + return pointcutExpression; + } + +} diff --git a/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/PointcutImpl.java b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/PointcutImpl.java new file mode 100644 index 000000000..adc1e9510 --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/internal/lang/reflect/PointcutImpl.java @@ -0,0 +1,60 @@ +/* ******************************************************************* + * 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.internal.lang.reflect; + +import java.lang.reflect.Method; + +import org.aspectj.lang.reflect.AjType; +import org.aspectj.lang.reflect.Pointcut; + +/** + * @author colyer + * + */ +public class PointcutImpl implements Pointcut { + + private final String name; + private final String pc; + private final Method baseMethod; + private final AjType declaringType; + + protected PointcutImpl(String name, String pc, Method method, AjType declaringType) { + this.name = name; + this.pc = pc; + this.baseMethod = method; + this.declaringType = declaringType; + } + + /* (non-Javadoc) + * @see org.aspectj.lang.reflect.Pointcut#getPointcutExpression() + */ + public String getPointcutExpression() { + return pc; + } + + public String getName() { + return name; + } + + public int getModifiers() { + return baseMethod.getModifiers(); + } + + public Class<?>[] getParameterTypes() { + return baseMethod.getParameterTypes(); + } + + public AjType getDeclaringType() { + return declaringType; + } + +} diff --git a/aspectj5rt/java5-src/org/aspectj/lang/annotation/AdviceName.java b/aspectj5rt/java5-src/org/aspectj/lang/annotation/AdviceName.java new file mode 100644 index 000000000..4e3ec7f9e --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/lang/annotation/AdviceName.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2005 Contributors. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Adrian Colyer initial implementation + *******************************************************************************/ +package org.aspectj.lang.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +/** + * Used to annotated code-style advice to name it + * Name is used by reflection api if present, may in future be used in adviceexecution() pcd. + * It is an error to use the @AdviceName annotation on an annotation-style advice declaration. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface AdviceName { + + /** + * The name of the advice + */ + String value(); +} diff --git a/aspectj5rt/java5-src/org/aspectj/lang/reflect/Advice.java b/aspectj5rt/java5-src/org/aspectj/lang/reflect/Advice.java index b31f94b6e..3fbc668cd 100644 --- a/aspectj5rt/java5-src/org/aspectj/lang/reflect/Advice.java +++ b/aspectj5rt/java5-src/org/aspectj/lang/reflect/Advice.java @@ -13,4 +13,9 @@ package org.aspectj.lang.reflect; public interface Advice { + AdviceType getKind(); + + String getName(); + + String getPointcutExpression(); } diff --git a/aspectj5rt/java5-src/org/aspectj/lang/reflect/AjType.java b/aspectj5rt/java5-src/org/aspectj/lang/reflect/AjType.java index 74f4b32db..19a30aa48 100644 --- a/aspectj5rt/java5-src/org/aspectj/lang/reflect/AjType.java +++ b/aspectj5rt/java5-src/org/aspectj/lang/reflect/AjType.java @@ -11,12 +11,13 @@ * ******************************************************************/ package org.aspectj.lang.reflect; -import java.lang.reflect.Method; +import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; -import java.lang.annotation.Annotation; +import java.util.Set; /** * The runtime representation of a type (Aspect, Class, Interface, Annotation, Enum, or Array) in an AspectJ @@ -96,9 +97,9 @@ public interface AjType<T> extends Type { // pointcuts - public Pointcut getDeclaredPointcut(String name); + public Pointcut getDeclaredPointcut(String name) throws NoSuchPointcutException; - public Pointcut getPointcut(String name); + public Pointcut getPointcut(String name) throws NoSuchPointcutException; public Pointcut[] getDeclaredPointcuts(); @@ -106,9 +107,13 @@ public interface AjType<T> extends Type { // advice - public Advice[] getDeclaredAdvice(AdviceType adviceType); + public Advice[] getDeclaredAdvice(AdviceType... ofTypes); + + public Advice[] getAdvice(AdviceType... ofTypes); + + public Advice getAdvice(String name) throws NoSuchAdviceException; - public Advice[] getAdvice(AdviceType adviceType); + public Advice getDeclaredAdvice(String name) throws NoSuchAdviceException; // inter-type declarations @@ -172,16 +177,6 @@ public interface AjType<T> extends Type { public boolean isMemberAspect(); + public boolean isPrivileged(); + } - - -// implementation notes: - -// additional runtime info we need: -// whether or not a class is an aspect -// pointcuts in a type (+ name, parameter types, parameter names, expression) -// itds in a type (is there enough in the class file already?) -// advice in a type (should be enough in the class file already?) -// declares in an aspect (+ associated info) - -// anchor in a generated static member on the type: ajc$reflectionInfo ? or use annotations??
\ No newline at end of file diff --git a/aspectj5rt/java5-src/org/aspectj/lang/reflect/AjTypeSystem.java b/aspectj5rt/java5-src/org/aspectj/lang/reflect/AjTypeSystem.java index e47fe6d8b..42d207804 100644 --- a/aspectj5rt/java5-src/org/aspectj/lang/reflect/AjTypeSystem.java +++ b/aspectj5rt/java5-src/org/aspectj/lang/reflect/AjTypeSystem.java @@ -11,6 +11,8 @@ * ******************************************************************/ package org.aspectj.lang.reflect; +import org.aspectj.internal.lang.reflect.AjTypeImpl; + /** * @author colyer * @@ -18,6 +20,6 @@ package org.aspectj.lang.reflect; public class AjTypeSystem { public static AjType getAjType(Class fromClass) { - return null; + return new AjTypeImpl(fromClass); } } diff --git a/aspectj5rt/java5-src/org/aspectj/lang/reflect/NoSuchAdviceException.java b/aspectj5rt/java5-src/org/aspectj/lang/reflect/NoSuchAdviceException.java new file mode 100644 index 000000000..e14dfb7d3 --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/lang/reflect/NoSuchAdviceException.java @@ -0,0 +1,31 @@ +/* ******************************************************************* + * 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.lang.reflect; + +/** + * @author colyer + * + */ +public class NoSuchAdviceException extends Exception { + + private static final long serialVersionUID = 3256444698657634352L; + private String name; + + public NoSuchAdviceException(String name) { + this.name = name; + } + + public String getName() { + return name; + } + +} diff --git a/aspectj5rt/java5-src/org/aspectj/lang/reflect/NoSuchPointcutException.java b/aspectj5rt/java5-src/org/aspectj/lang/reflect/NoSuchPointcutException.java new file mode 100644 index 000000000..df1bf9189 --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/lang/reflect/NoSuchPointcutException.java @@ -0,0 +1,31 @@ +/* ******************************************************************* + * 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.lang.reflect; + +/** + * @author colyer + * + */ +public class NoSuchPointcutException extends Exception { + + private static final long serialVersionUID = 3256444698657634352L; + private String name; + + public NoSuchPointcutException(String name) { + this.name = name; + } + + public String getName() { + return name; + } + +} diff --git a/aspectj5rt/java5-src/org/aspectj/lang/reflect/PerClause.java b/aspectj5rt/java5-src/org/aspectj/lang/reflect/PerClause.java index eab0b811e..7416ac09d 100644 --- a/aspectj5rt/java5-src/org/aspectj/lang/reflect/PerClause.java +++ b/aspectj5rt/java5-src/org/aspectj/lang/reflect/PerClause.java @@ -16,5 +16,6 @@ package org.aspectj.lang.reflect; * */ public interface PerClause { - + PerClauseKind getKind(); + String getPointcutExpression(); } diff --git a/aspectj5rt/java5-src/org/aspectj/lang/reflect/PerClauseKind.java b/aspectj5rt/java5-src/org/aspectj/lang/reflect/PerClauseKind.java new file mode 100644 index 000000000..03313d8c5 --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/lang/reflect/PerClauseKind.java @@ -0,0 +1,25 @@ +/* ******************************************************************* + * 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.lang.reflect; + +/** + * @author colyer + * The different perclauses (aspect instantiation models) + */ +public enum PerClauseKind { + SINGLETON, + PERTHIS, + PERTARGET, + PERCFLOW, + PERCFLOWBELOW, + PERTYPEWITHIN; +} diff --git a/aspectj5rt/java5-src/org/aspectj/lang/reflect/Pointcut.java b/aspectj5rt/java5-src/org/aspectj/lang/reflect/Pointcut.java index 398729ca4..0802db410 100644 --- a/aspectj5rt/java5-src/org/aspectj/lang/reflect/Pointcut.java +++ b/aspectj5rt/java5-src/org/aspectj/lang/reflect/Pointcut.java @@ -13,4 +13,13 @@ package org.aspectj.lang.reflect; public interface Pointcut { + String getPointcutExpression(); + + String getName(); + + int getModifiers(); + + Class<?>[] getParameterTypes(); + + AjType getDeclaringType(); } diff --git a/aspectj5rt/testsrc/Aspectj5rtModuleTests.java b/aspectj5rt/testsrc/Aspectj5rtModuleTests.java index 065df5479..ff1e30a2f 100644 --- a/aspectj5rt/testsrc/Aspectj5rtModuleTests.java +++ b/aspectj5rt/testsrc/Aspectj5rtModuleTests.java @@ -12,12 +12,19 @@ // default package -import junit.framework.*; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.aspectj.internal.lang.reflect.AjTypeTests; +import org.aspectj.internal.lang.reflect.AjTypeTestsWithAspects; public class Aspectj5rtModuleTests extends TestCase { public static Test suite() { TestSuite suite = new TestSuite("Aspectj5rt module tests"); + suite.addTestSuite(AjTypeTests.class); + suite.addTestSuite(AjTypeTestsWithAspects.class); return suite; } diff --git a/aspectj5rt/testsrc/org/aspectj/internal/lang/reflect/AjTypeTests.java b/aspectj5rt/testsrc/org/aspectj/internal/lang/reflect/AjTypeTests.java new file mode 100644 index 000000000..bae481e72 --- /dev/null +++ b/aspectj5rt/testsrc/org/aspectj/internal/lang/reflect/AjTypeTests.java @@ -0,0 +1,304 @@ +package org.aspectj.internal.lang.reflect; + +import java.io.Serializable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; + +import junit.framework.TestCase; + +import org.aspectj.lang.reflect.AjType; +import org.aspectj.lang.reflect.AjTypeSystem; + +public class AjTypeTests extends TestCase { + + private AjType stringType; + + @Override + protected void setUp() throws Exception { + super.setUp(); + stringType = AjTypeSystem.getAjType(String.class); + } + + public void testCreateAjType() { + assertNotNull("should find type",stringType); + } + + public void testGetName() { + assertEquals(String.class.getName(),stringType.getName()); + } + + public void testGetPackage() { + assertEquals(String.class.getPackage(),stringType.getPackage()); + } + + public void testGetInterfaces() { + Class[] i1 = String.class.getInterfaces(); + Class[] i2 = stringType.getInterfaces(); + assertEquals(i1.length,i2.length); + for (int i = 0; i < i1.length; i++) + assertEquals(i1[i],i2[i]); + } + + public void testGetModifiers() { + assertEquals(String.class.getModifiers(),stringType.getModifiers()); + } + + public void testGetSupertype() { + Class stringSuper = String.class.getSuperclass(); + AjType ajSuper = stringType.getSupertype(); + assertEquals(AjTypeSystem.getAjType(stringSuper),ajSuper); + } + + public void testGetGenericSupertype() { + Type t = AjTypeSystem.getAjType(Goo.class).getGenericSupertype(); + assertEquals(Foo.class,t); + } + + public void testGetEnclosingMethod() { + new Goo().foo(); + } + + public void testGetEnclosingConstructor() { + new Goo(); + } + + public void testGetEnclosingType() { + AjType t = AjTypeSystem.getAjType(Foo.Z.class); + assertEquals("org.aspectj.internal.lang.reflect.Foo",t.getEnclosingType().getName()); + } + + public void testGetDeclaringType() { + AjType t = AjTypeSystem.getAjType(Foo.Z.class); + assertEquals("org.aspectj.internal.lang.reflect.Foo",t.getDeclaringType().getName()); + } + + public void testIsAnnotationPresent() { + AjType<Foo> foo = AjTypeSystem.getAjType(Foo.class); + AjType<Goo> goo = AjTypeSystem.getAjType(Goo.class); + assertTrue(foo.isAnnotationPresent(SomeAnn.class)); + assertFalse(goo.isAnnotationPresent(SomeAnn.class)); + } + + public void testGetAnnotation() { + AjType<Foo> foo = AjTypeSystem.getAjType(Foo.class); + AjType<Goo> goo = AjTypeSystem.getAjType(Goo.class); + assertNotNull(foo.getAnnotation(SomeAnn.class)); + assertNull(goo.getAnnotation(SomeAnn.class)); + } + + public void testGetAnnotations() { + AjType<Foo> foo = AjTypeSystem.getAjType(Foo.class); + AjType<Goo> goo = AjTypeSystem.getAjType(Goo.class); + assertEquals(1,foo.getAnnotations().length); + assertEquals(0,goo.getAnnotations().length); + } + + public void testGetDeclaredAnnotations() { + AjType<Foo> foo = AjTypeSystem.getAjType(Foo.class); + AjType<Goo> goo = AjTypeSystem.getAjType(Goo.class); + assertEquals(0,goo.getDeclaredAnnotations().length); + assertEquals(1,foo.getDeclaredAnnotations().length); + } + + public void testGetAjTypes() { + AjType<Foo> foo = AjTypeSystem.getAjType(Foo.class); + AjType[] fooTypes = foo.getAjTypes(); + assertEquals(1,fooTypes.length); + assertEquals("org.aspectj.internal.lang.reflect.Foo$Z",fooTypes[0].getName()); + } + + public void testGetDeclaredAjTypes() { + AjType<Foo> foo = AjTypeSystem.getAjType(Foo.class); + AjType[] fooTypes = foo.getDeclaredAjTypes(); + assertEquals(2,fooTypes.length); + assertEquals("org.aspectj.internal.lang.reflect.Foo$Z",fooTypes[0].getName()); + assertEquals("org.aspectj.internal.lang.reflect.Foo$XX",fooTypes[1].getName()); + } + + public void testGetConstructor() throws Exception { + Constructor c1 = String.class.getConstructor(String.class); + Constructor c2 = stringType.getConstructor(String.class); + assertEquals(c1,c2); + } + + public void testGetConstructors() { + Constructor[] c1 = String.class.getConstructors(); + Constructor[] c2 = stringType.getConstructors(); + assertEquals(c1.length,c2.length); + for (int i = 0; i < c1.length; i++) + assertEquals(c1[i],c2[i]); + } + + public void testGetDeclaredConstructor() throws Exception { + Constructor c1 = String.class.getDeclaredConstructor(String.class); + Constructor c2 = stringType.getDeclaredConstructor(String.class); + assertEquals(c1,c2); + } + + public void testGetDeclaredConstructors() { + Constructor[] c1 = String.class.getDeclaredConstructors(); + Constructor[] c2 = stringType.getDeclaredConstructors(); + assertEquals(c1.length,c2.length); + for (int i = 0; i < c1.length; i++) + assertEquals(c1[i],c2[i]); + } + + public void testGetDeclaredField() throws Exception { + Field f1 = String.class.getDeclaredField("value"); + Field f2 = stringType.getDeclaredField("value"); + assertEquals(f1,f2); + } + + public void testGetDeclaredFields() { + Field[] f1 = String.class.getDeclaredFields(); + Field[] f2 = stringType.getDeclaredFields(); + assertEquals(f1.length,f2.length); + for (int i = 0; i < f1.length; i++) + assertEquals(f1[i],f2[i]); + } + + public void testGetField() throws Exception { + AjType<Goo> goo = AjTypeSystem.getAjType(Goo.class); + assertEquals("g",goo.getField("g").getName()); + } + + public void testGetFields() { + AjType<Goo> goo = AjTypeSystem.getAjType(Goo.class); + Field[] fields = goo.getFields(); + assertEquals(1,fields.length); + assertEquals("g",fields[0].getName()); + + } + + public void testGetDeclaredMethod() throws Exception { + Method m1 = String.class.getDeclaredMethod("toUpperCase"); + Method m2 = stringType.getDeclaredMethod("toUpperCase"); + assertEquals(m1,m2); + } + + public void testGetMethod() throws Exception { + Method m1 = String.class.getMethod("toUpperCase"); + Method m2 = stringType.getMethod("toUpperCase"); + assertEquals(m1,m2); + } + + public void testGetDeclaredMethods() { + Method[] m1 = String.class.getDeclaredMethods(); + Method[] m2 = stringType.getDeclaredMethods(); + assertEquals(m1.length,m2.length); + for (int i = 0; i < m1.length; i++) + assertEquals(m1[i],m2[i]); + } + + public void testGetMethods() { + Method[] m1 = String.class.getMethods(); + Method[] m2 = stringType.getMethods(); + assertEquals(m1.length,m2.length); + for (int i = 0; i < m1.length; i++) + assertEquals(m1[i],m2[i]); + } + + public void testGetEnumConstants() { + AjType e = AjTypeSystem.getAjType(E.class); + Object[] consts = e.getEnumConstants(); + assertEquals(3,consts.length); + } + + public void testGetTypeParameters() { + AjType<Foo> foo = AjTypeSystem.getAjType(Foo.class); + TypeVariable<Class<Foo>>[] tvs = foo.getTypeParameters(); + assertEquals(1,tvs.length); + assertEquals("T",tvs[0].getName()); + } + + public void testIsEnum() { + assertFalse(stringType.isEnum()); + } + + public void testIsInstance() { + assertTrue(stringType.isInstance("I am")); + } + + public void testIsInterface() { + assertFalse(stringType.isInterface()); + assertTrue(AjTypeSystem.getAjType(Serializable.class).isInterface()); + } + + public void testIsLocalClass() { + assertFalse(stringType.isLocalClass()); + } + + public void testIsArray() { + assertFalse(stringType.isArray()); + assertTrue(AjTypeSystem.getAjType(Integer[].class).isArray()); + } + + public void testIsPrimitive() { + assertFalse(stringType.isPrimitive()); + assertTrue(AjTypeSystem.getAjType(boolean.class).isPrimitive()); + } + + public void testIsAspect() { + assertFalse(stringType.isAspect()); + } + + public void testIsMemberAspect() { + assertFalse(stringType.isMemberAspect()); + } + + public void testIsPrivileged() { + assertFalse(stringType.isPrivileged()); + } + + public void testEquals() { + AjType stringTypeTwo = AjTypeSystem.getAjType(String.class); + assertTrue(stringType.equals(stringTypeTwo)); + } + + public void testHashCode() { + AjType stringTypeTwo = AjTypeSystem.getAjType(String.class); + assertEquals(stringType.hashCode(),stringTypeTwo.hashCode()); + } + +} + +@Retention(RetentionPolicy.RUNTIME) +@interface SomeAnn {} + +@SomeAnn +class Foo<T> { + + public Foo() { + class Y { int y; } + AjType t = AjTypeSystem.getAjType(Y.class); + Constructor c = t.getEnclosingConstructor(); + if (!c.getName().equals("org.aspectj.internal.lang.reflect.Foo")) throw new RuntimeException("should have been Foo"); + } + public void foo() { + class X { int x; } + AjType t = AjTypeSystem.getAjType(X.class); + Method m = t.getEnclosingMethod(); + if (!m.getName().equals("foo")) throw new RuntimeException("should have been foo"); + } + public class Z { int z; } + class XX { int xx; } +} + +class Goo extends Foo { + @interface IX {} + + public Goo() { + super(); + } + + public int g; + int g2; + +} + +enum E { A,B,C; } diff --git a/aspectj5rt/testsrc/org/aspectj/internal/lang/reflect/AjTypeTestsWithAspects.java b/aspectj5rt/testsrc/org/aspectj/internal/lang/reflect/AjTypeTestsWithAspects.java new file mode 100644 index 000000000..0972a67f4 --- /dev/null +++ b/aspectj5rt/testsrc/org/aspectj/internal/lang/reflect/AjTypeTestsWithAspects.java @@ -0,0 +1,371 @@ +package org.aspectj.internal.lang.reflect; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.EnumSet; +import java.util.Set; + +import junit.framework.TestCase; + +import org.aspectj.internal.lang.annotation.ajcPrivileged; +import org.aspectj.lang.annotation.AdviceName; +import org.aspectj.lang.annotation.After; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.reflect.Advice; +import org.aspectj.lang.reflect.AdviceType; +import org.aspectj.lang.reflect.AjType; +import org.aspectj.lang.reflect.AjTypeSystem; +import org.aspectj.lang.reflect.NoSuchAdviceException; +import org.aspectj.lang.reflect.NoSuchPointcutException; +import org.aspectj.lang.reflect.PerClause; +import org.aspectj.lang.reflect.PerClauseKind; +import org.aspectj.lang.reflect.Pointcut; + +public class AjTypeTestsWithAspects extends TestCase { + + private AjType sa; + + protected void setUp() throws Exception { + super.setUp(); + sa = AjTypeSystem.getAjType(SimpleAspect.class); + } + + public void testGetPerClause() { + AjType perThisA = AjTypeSystem.getAjType(PerThisAspect.class); + AjType perTargetA = AjTypeSystem.getAjType(PerTargetAspect.class); + AjType perCflowA = AjTypeSystem.getAjType(PerCflowAspect.class); + AjType perCflowbelowA = AjTypeSystem.getAjType(PerCflowbelowAspect.class); + AjType perTypeWithinA = AjTypeSystem.getAjType(PerTypeWithin.class); + + PerClause pc = perThisA.getPerClause(); + assertEquals(PerClauseKind.PERTHIS,pc.getKind()); + assertEquals("pc()",pc.getPointcutExpression()); + + pc= perTargetA.getPerClause(); + assertEquals(PerClauseKind.PERTARGET,pc.getKind()); + assertEquals("pc()",pc.getPointcutExpression()); + + pc= perCflowA.getPerClause(); + assertEquals(PerClauseKind.PERCFLOW,pc.getKind()); + assertEquals("pc()",pc.getPointcutExpression()); + + pc= perCflowbelowA.getPerClause(); + assertEquals(PerClauseKind.PERCFLOWBELOW,pc.getKind()); + assertEquals("pc()",pc.getPointcutExpression()); + + pc= perTypeWithinA.getPerClause(); + assertEquals(PerClauseKind.PERTYPEWITHIN,pc.getKind()); + assertEquals("org.aspectj..*",pc.getPointcutExpression()); + + } + + public void testGetDeclaredField() throws Exception{ + Field f = sa.getDeclaredField("s"); + try { + Field f2 = sa.getDeclaredField("ajc$xyz$s"); + fail("Expecting NoSuchFieldException"); + } catch (NoSuchFieldException nsf) {} + } + + public void testGetField() throws Exception { + Field f = sa.getField("s"); + try { + Field f2 = sa.getField("ajc$xyz$s"); + fail("Expecting NoSuchFieldException"); + } catch (NoSuchFieldException nsf) {} + } + + public void testGetDeclaredFields() { + Field[] fields = sa.getDeclaredFields(); + assertEquals(1,fields.length); + assertEquals("s",fields[0].getName()); + } + + public void testGetFields() { + Field[] fields = sa.getFields(); + assertEquals(1,fields.length); + assertEquals("s",fields[0].getName()); + } + + public void testGetDeclaredMethod() throws Exception { + Method m = sa.getDeclaredMethod("aMethod"); + try { + Method m2 = sa.getDeclaredMethod("logEntry"); + fail("Expecting NoSuchMethodException"); + } catch(NoSuchMethodException ex) {} + try { + Method m3 = sa.getDeclaredMethod("ajc$before$123"); + fail("Expecting NoSuchMethodException"); + } catch(NoSuchMethodException ex) {} + } + + public void testGetMethod() throws Exception { + Method m = sa.getMethod("aMethod"); + try { + Method m2 = sa.getMethod("logEntry"); + fail("Expecting NoSuchMethodException"); + } catch(NoSuchMethodException ex) {} + try { + Method m3 = sa.getMethod("ajc$before$123"); + fail("Expecting NoSuchMethodException"); + } catch(NoSuchMethodException ex) {} + } + + public void testGetDeclaredMethods() { + Method[] ms = sa.getDeclaredMethods(); + assertEquals(1,ms.length); + assertEquals("aMethod",ms[0].getName()); + } + + public void testGetMethods() { + Method[] ms = sa.getMethods(); + assertEquals(10,ms.length); + assertEquals("aMethod",ms[0].getName()); + } + + public void testGetDeclaredPointcut() throws Exception { + Pointcut p1 = sa.getDeclaredPointcut("simpleAspectMethodExecution"); + assertEquals("simpleAspectMethodExecution",p1.getName()); + assertEquals("execution(* SimpleAspect.*(..))",p1.getPointcutExpression()); + assertEquals(sa,p1.getDeclaringType()); + assertEquals(0,p1.getParameterTypes().length); + assertTrue(Modifier.isPublic(p1.getModifiers())); + Pointcut p2 = sa.getDeclaredPointcut("simpleAspectCall"); + assertEquals("simpleAspectCall",p2.getName()); + assertEquals("call(* SimpleAspect.*(..))",p2.getPointcutExpression()); + assertEquals(sa,p2.getDeclaringType()); + assertEquals(1,p2.getParameterTypes().length); + assertTrue(Modifier.isPrivate(p2.getModifiers())); + try { + Pointcut p3 = sa.getDeclaredPointcut("sausages"); + fail("Expecting NoSuchPointcutExcetpion"); + } catch (NoSuchPointcutException ex) { + assertEquals("sausages",ex.getName()); + } + } + + public void testGetPointcut() throws Exception { + Pointcut p1 = sa.getPointcut("simpleAspectMethodExecution"); + assertEquals("simpleAspectMethodExecution",p1.getName()); + assertEquals("execution(* SimpleAspect.*(..))",p1.getPointcutExpression()); + assertEquals(sa,p1.getDeclaringType()); + assertEquals(0,p1.getParameterTypes().length); + assertTrue(Modifier.isPublic(p1.getModifiers())); + Pointcut p2 = sa.getPointcut("simpleAspectCall"); + assertEquals("simpleAspectCall",p2.getName()); + assertEquals("call(* SimpleAspect.*(..))",p2.getPointcutExpression()); + assertEquals(sa,p2.getDeclaringType()); + assertEquals(1,p2.getParameterTypes().length); + assertTrue(Modifier.isPrivate(p2.getModifiers())); + try { + Pointcut p3 = sa.getPointcut("sausages"); + fail("Expecting NoSuchPointcutExcetpion"); + } catch (NoSuchPointcutException ex) { + assertEquals("sausages",ex.getName()); + } + } + + public void testGetDeclaredPointcuts() { + Pointcut[] pcs = sa.getDeclaredPointcuts(); + assertEquals(2,pcs.length); + assertEquals("simpleAspectMethodExecution",pcs[0].getName()); + assertEquals("simpleAspectCall",pcs[1].getName()); + } + + public void testGetPointcuts() { + Pointcut[] pcs = sa.getPointcuts(); + assertEquals(1,pcs.length); + assertEquals("simpleAspectMethodExecution",pcs[0].getName()); + } + + public void testGetDeclaredAdvice() { + Advice[] advice = sa.getDeclaredAdvice(); + assertEquals(10,advice.length); + advice = sa.getDeclaredAdvice(AdviceType.BEFORE); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceType.AFTER); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceType.AFTER_RETURNING); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceType.AFTER_THROWING); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceType.AROUND); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceType.BEFORE,AdviceType.AFTER); + assertEquals(4,advice.length); + + advice = sa.getDeclaredAdvice(AdviceType.BEFORE); + assertEquals("execution(* SimpleAspect.*(..))",advice[0].getPointcutExpression()); + assertEquals("logEntry",advice[0].getName()); + assertEquals(AdviceType.BEFORE,advice[0].getKind()); + assertEquals("execution(* SimpleAspect.*(..))",advice[1].getPointcutExpression()); + assertEquals("",advice[1].getName()); + } + + public void testGetAdvice() { + Advice[] advice = sa.getDeclaredAdvice(); + assertEquals(10,advice.length); + advice = sa.getDeclaredAdvice(AdviceType.BEFORE); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceType.AFTER); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceType.AFTER_RETURNING); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceType.AFTER_THROWING); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceType.AROUND); + assertEquals(2,advice.length); + advice = sa.getDeclaredAdvice(AdviceType.BEFORE,AdviceType.AFTER); + assertEquals(4,advice.length); + } + + public void testGetNamedAdvice() throws Exception { + Advice a = sa.getAdvice("logItAll"); + assertEquals("logItAll",a.getName()); + assertEquals(AdviceType.AROUND,a.getKind()); + a = sa.getAdvice("whatGoesAround"); + assertEquals("whatGoesAround",a.getName()); + assertEquals(AdviceType.AROUND,a.getKind()); + try { + a = sa.getAdvice("ajc$after$123"); + fail("Expecting NoSuchAdviceException"); + } catch (NoSuchAdviceException ex) { + assertEquals("ajc$after$123",ex.getName()); + } + try { + a = sa.getAdvice(""); + fail("Expecting IllegalArgumentException"); + } catch (IllegalArgumentException ex) { + ; + } + } + + public void testGetNamedDeclaredAdvice() throws Exception { + Advice a = sa.getDeclaredAdvice("logItAll"); + assertEquals("logItAll",a.getName()); + assertEquals(AdviceType.AROUND,a.getKind()); + a = sa.getDeclaredAdvice("whatGoesAround"); + assertEquals("whatGoesAround",a.getName()); + assertEquals(AdviceType.AROUND,a.getKind()); + try { + a = sa.getDeclaredAdvice("ajc$after$123"); + fail("Expecting NoSuchAdviceException"); + } catch (NoSuchAdviceException ex) { + assertEquals("ajc$after$123",ex.getName()); + } + try { + a = sa.getDeclaredAdvice(""); + fail("Expecting IllegalArgumentException"); + } catch (IllegalArgumentException ex) { + ; + } + } + + public void testIsPrivileged() { + assertFalse(sa.isPrivileged()); + assertTrue(AjTypeSystem.getAjType(SimplePrivilegedAspect.class).isPrivileged()); + } + + public void testIsAspect() { + assertTrue(sa.isAspect()); + } + + public void testIsMemberAspect() { + assertFalse(AjTypeSystem.getAjType(SimplePrivilegedAspect.class).isMemberAspect()); + assertTrue(AjTypeSystem.getAjType(SimplePrivilegedAspect.MemberAspect.class).isMemberAspect()); + + } +} + + +@Aspect +class SimpleAspect { + + // regular field + public String s; + + // synthetic field + public String ajc$xyz$s; + + // regular method + public void aMethod() {} + + // advice method, annotation style + @Before("execution(* SimpleAspect.*(..))") + public void logEntry() {} + + // advice method, code style + @Before("execution(* SimpleAspect.*(..))") + public void ajc$before$123() {} + + // advice method, annotation style + @After("execution(* SimpleAspect.*(..))") + public void logFinally() {} + + // advice method, code style + @After("execution(* SimpleAspect.*(..))") + public void ajc$after$123() {} + + // advice method, annotation style + @AfterReturning("execution(* SimpleAspect.*(..))") + public void logExit() {} + + // advice method, code style + @AfterReturning("execution(* SimpleAspect.*(..))") + public void ajc$afterReturning$123() {} + + // advice method, annotation style + @AfterThrowing("execution(* SimpleAspect.*(..))") + public void logException() {} + + // advice method, code style + @AfterThrowing("execution(* SimpleAspect.*(..))") + public void ajc$afterThrowing$123() {} + + // advice method, annotation style + @Around("execution(* SimpleAspect.*(..))") + public void logItAll() {} + + // advice method, code style + @Around("execution(* SimpleAspect.*(..))") + @AdviceName("whatGoesAround") + public void ajc$around$123() {} + + // pointcut, annotation style + @org.aspectj.lang.annotation.Pointcut("execution(* SimpleAspect.*(..))") + public void simpleAspectMethodExecution() {}; + + // pointcut, code style + @org.aspectj.lang.annotation.Pointcut("call(* SimpleAspect.*(..))") + private void ajc$pointcut$$simpleAspectCall$123(SimpleAspect target) {}; + +} + +@Aspect +@ajcPrivileged +class SimplePrivilegedAspect { + + @Aspect + static class MemberAspect {} + +} + +@Aspect("perthis(pc())") +class PerThisAspect {} + +@Aspect("pertarget(pc())") +class PerTargetAspect {} + +@Aspect("percflow(pc())") +class PerCflowAspect {} + +@Aspect("percflowbelow(pc())") +class PerCflowbelowAspect {} + +@Aspect("pertypewithin(org.aspectj..*)") +class PerTypeWithin {} diff --git a/lib/test/aspectjrt.jar b/lib/test/aspectjrt.jar Binary files differindex 105609e1e..8ee14c02c 100644 --- a/lib/test/aspectjrt.jar +++ b/lib/test/aspectjrt.jar |